Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用perl无法正确嵌套从JSON创建的XML_Json_Xml_Perl_Nested Attributes_Data Conversion - Fatal编程技术网

使用perl无法正确嵌套从JSON创建的XML

使用perl无法正确嵌套从JSON创建的XML,json,xml,perl,nested-attributes,data-conversion,Json,Xml,Perl,Nested Attributes,Data Conversion,我正在尝试使用perl脚本将JSON数据转换为XML。但是转换后的JSON没有预期的标记。下面是我使用的输入、代码和收到的输出 {"status": "Success", "output": {"product_artifacts": [ {"variant_name": "test_var", "artifacts": [ {"artifact_create

我正在尝试使用perl脚本将JSON数据转换为XML。但是转换后的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":
     []
 }
上面的Json在传递到下面的Perl脚本时,没有按预期创建XML: Perl脚本:

#!/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";
#/app/perl/5.16.2/LMWP3/bin/perl
严格使用;
使用警告;
binmode标准输出“:utf8”;
使用utf8;
使用JSON;
使用XML::Simple;
#读取json格式的输入文件
我的美元是多少
{“状态”:“成功”,
“产出”:
{“产品_工件”:
[
{“variant_name”:“test_var”,
“文物”:
[
{“创造的神器”:“10-25-19 15:52:02”,
“工件下载链接”:http://abc:rt/ ",
“工件数字尺寸”:123,
“工件编号”:“123/234”,
“工件修订”:“AB1”}
]
}
]
},
“信息”:
[]
}';
#将JSON格式转换为perl结构
my$data=decode_json($json);
#输出为XML
打印“\n”;
打印XMLout(数据);
打印“\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>

预期输出:

 <?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>

成功
测试变量
10-25-19 15:52:02
http://asd:rt 
123
1234
自动控制

有人能帮我解决哪里出了问题吗

目前还没有解决方案

让我提供一个可能的简单解决方案,不使用任何perl模块

use strict;
use warnings;
use feature 'say';

use JSON;

binmode STDOUT, ":utf8";
use utf8;

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);

say json2xml($data);

sub json2xml {
    my $data  = shift;

    my $xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";

    $xml .= "<root>\n";
    $xml .= j2x($data,1);
    $xml .= "</root>\n";

    return $xml;
}

sub j2x {
    my $json  = shift;
    my $depth = shift;

    my $xml;
    my $indent = 2;
    my $space = ' ' x ($depth*$indent);

    while( my($k,$v) = each %{$json} ) {
        if( ref $v eq 'HASH' ) {
            $xml .= $space . "<$k>\n";
            $xml .= j2x($v,$depth+1);
            $xml .= $space . "</$k>\n";
        } elsif ( ref $v eq 'ARRAY' ) {
            $xml .= $space . "<$k>\n";
            foreach my $e (@{$v}) {
                $xml .= j2x($e,$depth+1);
            }
            $xml .= $space . "</$k>\n";
        } else {
            $xml .= $space . "<$k>$v</$k>\n";
        }
    }

    return $xml;
}
使用严格;
使用警告;
使用特征“说”;
使用JSON;
binmode标准输出“:utf8”;
使用utf8;
我的美元是多少
{“状态”:“成功”,
“产出”:
{“产品_工件”:
[
{
“变量名称”:“测试变量”,
“文物”:
[
{
“创造的神器”:“10-25-19 15:52:02”,
“工件下载链接”:http://abc:rt/ ",
“工件数字尺寸”:123,
“工件编号”:“123/234”,
“工件修订”:“AB1”
}
]
}
]
},
“信息”:[]
}';
#将JSON格式转换为perl结构
my$data=decode_json($json);
比如json2xml($data);
子json2xml{
我的$data=shift;
my$xml=“\n”;
$xml.=“\n”;
$xml.=j2x($data,1);
$xml.=“\n”;
返回$xml;
}
子j2x{
我的$json=shift;
我的$depth=shift;
我的$xml;
我的$indent=2;
my$space=''x($depth*$indent);
而(my($k,$v)=每个%{$json}){
如果(参考$v等式“哈希”){
$xml.=$space.“\n”;
$xml.=j2x($v,$depth+1);
$xml.=$space.“\n”;
}elsif(参考$v均衡器“阵列”){
$xml.=$space.“\n”;
每个我的$e(@{$v}){
$xml.=j2x($e,$depth+1);
}
$xml.=$space.“\n”;
}否则{
$xml.=$space.“$v\n”;
}
}
返回$xml;
}
输出与所需略有不同,因为代码未考虑空xml元素(在这种情况下为空JSON数组)


成功
测试变量
123/234
10-25-19 15:52:02
AB1
123
http://abc:rt/ 

注意:在OP的post中,JSON和所需输出不匹配,因此生成的输出是post中给出的JSON数据的表示形式。Perl数据结构不直接映射到XML。例如,位于某个位置的hashref可以由标记上的属性或嵌套标记表示,这些标记本身可能具有属性、标记或文本。因此,要以您想要的方式格式化输出,一种方法是使用模板来定义您想要的结构,例如使用

使用严格;
使用警告;
使用Mojo::模板;
my$tmpl={output}{product_artifacts}}){
{variant_name}%>
可用于此目的

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;
使用严格;
使用警告;
使用Mojo::DOM;
my$dom=Mojo::dom->new->xml(1)->parse(“”);
my$root=$dom->at('root');
$root->append_content($dom->new_标记('status',$data->{status}));
$root->append_content($dom->new_标记('output'));
my$output=$root->at('output');
$output->append_content($dom->new_标记('product_artifacts');
我的$product_工件=$output->at('product_工件');
foreach my$variant(@{$data->{output}{product_artifacts}}){
$product_artifacts->append_内容($dom->new_标记('variant_name',$variant->{variant_name}));
$product_artifacts->append_content($dom->new_标记('artifacts');
my$artifacts=$product_artifacts->at('artifacts');
foreach my$artifact(@{$variant->{artifacts}){
foreach my$密钥(排序密钥%$工件){
$artifact->append_内容($dom->new_标记($key,$artifact->{$key}));
}
}
}
$root->append_content($dom->new_标记('message',$data->{message}));
my$xml=$dom->to_字符串;

这些示例都将XML作为字符生成;当输出到文件或其他文件时,应将其编码为UTF-8。

请注意,XML::Simple已被弃用,作者本人建议使用其他模块。 但是,我不知道有一个模块可以用来轻松地将数据结构转储到XML中(除了XML::Dumper,但它有一个非常不同的输出结构),而无需“手动”构造数据结构

对于所需的输出格式,需要为XMLOut函数设置以下选项:

print XMLout($data,NoAttr => 1, RootName => 'root');
然而,这仍然会留下“message”标记,它是一个空数组,而XML::Simple似乎会悄悄地丢弃它(耶!)


XML::Simple很糟糕。它不一致,其文档不鼓励使用它。请不要因为没有人提供解决方案而提供解决方案。此解决方案不会对XML值进行转义。正确的解决方案是使用XML呈现器或XML模板器(我的建议是Text::Xslate或Mo)
<root>
  <output>
    <product_artifacts>
      <artifacts>
        <artifact_created>10-25-19 15:52:02</artifact_created>
        <artifact_digital_size>123</artifact_digital_size>
        <artifact_download_link>http://abc:rt/ </artifact_download_link>
        <artifact_number>123/234</artifact_number>
        <artifact_revision>AB1</artifact_revision>
      </artifacts>
      <variant_name>test_var</variant_name>
    </product_artifacts>
  </output>
  <status>Success</status>
</root>
#!/app/perl/5.16.2/LMWP3/bin/perl

use strict;
use warnings;

binmode STDOUT, ":utf8";
use utf8;



use JSON;

use XML::Writer;

# Read input file in json format
my $json = qq(
{
  "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": []
}
);
my $data = decode_json($json);
my $writer = XML::Writer->new( OUTPUT => 'self',DATA_MODE => 1, DATA_INDENT => 4);

$writer->xmlDecl("UTF-8");
$writer->startTag('root');
    $writer->dataElement(status => $data->{status});
    $writer->startTag('output');
       for my $p (@{$data->{output}{product_artifacts}}) {
           $writer->startTag('product_artifacts');
           $writer->dataElement($_ => $p->{$_}) for qw(variant_name);
           for my $a (@{$p->{artifacts}}) {
               $writer->startTag('artifacts');
               $writer->dataElement($_ => $a->{$_}) for qw(artifact_created
                                                       artifact_download_link
                                                       artifact_digital_size
                                                       artifact_number
                                                       artifact_revision);
               $writer->endTag('artifacts');
           }
           $writer->endTag('product_artifacts');
       }
    $writer->endTag('output');
    $writer->emptyTag('message');
$writer->endTag('root');

print $writer->to_string();
print "\n";