使用 perl 从 JSON 创建的 XML 未正确嵌套 [英] XML created from JSON is not correctly nested using perl

查看:71
本文介绍了使用 perl 从 JSON 创建的 XML 未正确嵌套的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 perl 脚本将 JSON 数据转换为 XML.但是转换后的 JSON 没有预期的标签.以下是我使用的输入、代码和收到的输出

I'm trying to convert JSON data to XML using perl script. But the JSON when converted is not having the expected tags. Below is the input, code I used and output I received

{"status": "Success",
 "output":
     {"product_artifacts":
         [
             {"variant_name": "test_var",
 "artifacts":
                  [
                      {"artifact_created": "10-25-19 15:52:02",
 "artifact_download_link": "http://abc:rt/ ",
 "artifact_digital_size": 123,
 "artifact_number": "123/234",
 "artifact_revision": "AB1"}
                  ]
              }
         ]
      },
 "message":
     []
 }

当传递给下面的 Perl 脚本时,上面的 Json 没有按预期创建 XML:Perl 脚本:

Above Json when passed to the below Perl script, is not creating the XML as expected: Perl Script :

#!/app/perl/5.16.2/LMWP3/bin/perl

use strict;
use warnings;

binmode STDOUT, ":utf8";
use utf8;



use JSON;
use XML::Simple;

# Read input file in json format
my $json = '
{"status": "Success",
 "output":
     {"product_artifacts":
         [
             {"variant_name": "test_var",
 "artifacts":
                  [
                      {"artifact_created": "10-25-19 15:52:02",
 "artifact_download_link": "http://abc:rt/ ",
 "artifact_digital_size": 123,
 "artifact_number": "123/234",
 "artifact_revision": "AB1"}
                  ]
              }
         ]
      },
 "message":
     []
 }';

# Convert JSON format to perl structures
my $data = decode_json($json);

# Output as XML
print "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
print XMLout($data);
print "\n";

实际输出:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<opt status="Success">
  <output>
    <product_artifacts variant_name="test_var">
      <artifacts artifact_created="10-25-19 15:52:02" artifact_digital_size="9293792" artifact_download_link="http://abc:rt " artifact_number="123/234" artifact_revision="AC" />
    </product_artifacts>
  </output>
</opt>

预期输出:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <status>Success</status>
  <output>
    <product_artifacts>
      <variant_name>test_var</variant_name>
      <artifacts>
        <artifact_created>10-25-19 15:52:02</artifact_created>
        <artifact_download_link>http://asd:rt </artifact_download_link>
        <artifact_digital_size>123</artifact_digital_size>
        <artifact_number>1234</artifact_number>
        <artifact_revision>AC</artifact_revision>
      </artifacts>
    </product_artifacts>
  </output>
  <message/>
</root>

有人可以帮助我出错的地方

Can someone help where I'm going wrong

推荐答案

Perl 数据结构不直接映射到 XML.例如,某个位置的 hashref 可以由标签上的属性或嵌套标签表示,这些标签本身可能具有属性、标签或文本.因此,要按照您想要的方式格式化输出,一种方法是使用模板来定义您想要的结构,例如使用 Mojo::Template.

Perl data structures do not directly map to XML. A hashref at a certain position for instance could be represented by attributes on a tag, or nested tags, which themselves might have attributes, tags, or text. So to get the output formatted the way you want, one way is to use templating to define the structure you want, such as with Mojo::Template.

use strict;
use warnings;
use Mojo::Template;

my $tmpl = <<'TMPL';
<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <status><%= $data->{status} %></status>
  <output>
    <product_artifacts>
    % foreach my $variant (@{$data->{output}{product_artifacts}}) {
      <variant_name><%= $variant->{variant_name} %></variant_name>
      <artifacts>
      % foreach my $artifact (@{$variant->{artifacts}}) {
        % foreach my $key (sort keys %$artifact) {
          <<%= $key %>><%= $artifact->{$key} %></<%= $key %>>
        % }
      % }
      </artifacts>
    % }
    </product_artifacts>
  </output>
  <message/>
</root>
TMPL

my $t = Mojo::Template->new(auto_escape => 1, vars => 1);
my $xml = $t->render($tmpl, {data => $data});

您的预期格式仍然有些不清楚 - 例如,如果您在这些数组中获得多个变体或工件,请考虑应该如何布局.这些是自动转换不太可能满足您需要的一些原因.

Your expected format is still somewhat unclear - for example, consider how it should be laid out should you get multiple variants or artifacts in those arrays. These are some of the reasons automatic conversion is unlikely to do what you need.

另一种方法是使用 XML 遍历工具适当地构建 XML,这有点繁琐但意味着您不需要手动编写标签,Mojo::DOM 可用于此目的.

Another approach is to use an XML traversal tool to build the XML appropriately, which is a bit more tedious but means you don't need to manually write tags, Mojo::DOM can be used for this purpose.

use strict;
use warnings;
use Mojo::DOM;

my $dom = Mojo::DOM->new->xml(1)->parse('<?xml version="1.0" encoding="UTF-8" ?><root/>');

my $root = $dom->at('root');
$root->append_content($dom->new_tag('status', $data->{status}));
$root->append_content($dom->new_tag('output'));
my $output = $root->at('output');
$output->append_content($dom->new_tag('product_artifacts'));
my $product_artifacts = $output->at('product_artifacts');
foreach my $variant (@{$data->{output}{product_artifacts}}) {
  $product_artifacts->append_content($dom->new_tag('variant_name', $variant->{variant_name}));
  $product_artifacts->append_content($dom->new_tag('artifacts'));
  my $artifacts = $product_artifacts->at('artifacts');
  foreach my $artifact (@{$variant->{artifacts}}) {
    foreach my $key (sort keys %$artifact) {
      $artifacts->append_content($dom->new_tag($key, $artifact->{$key}));
    }
  }
}
$root->append_content($dom->new_tag('message', $data->{message}));

my $xml = $dom->to_string;

这些示例都将 XML 作为字符;当输出到文件或其他方式时,它应该被编码为 UTF-8.

These examples both result in the XML as characters; it should be encoded to UTF-8 when output to a file or otherwise.

这篇关于使用 perl 从 JSON 创建的 XML 未正确嵌套的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆