为什么Perl中的XML :: simple模块没有输出预期的格式?

时间:2012-03-22 03:30:52

标签: xml perl

我目前正在尝试编写一个可以将XML写入文件的Perl函数。建议使用的模块是XML::Simple。我已经编写了下面的代码,我看到了XML输出,但是我没有看到我想要输出的内容。我附上了我的代码,结果和我的预期输出。我做错了什么?

#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;

sub writexmlout {
  my $hashref = {
        'Contracts' => {
           'ShortName' => '123231123'
         },
         'CallStates' => {
            'CallStatesSPR' => {
           'Name' => 'Acknowledged'
             }
         },
         'ContractElements' => {
             'ShortName' => 'test'
         },
         'Calls' => {
             'CHD' => {
                 'FirstName' => 'Ron',
                 'LastName' => 'Rich',
                 'Tel' => '(123)  456-4567',
                 'Sign' => 'B2B',
                 'Email' => 'ron.rich@mavenir.com'
             },
             'SPCallID' => '12',
             'Remarks' => 'Ticket successfully Ebonded',
             'CustCallID' => '6199999'
         }
  };

  # Create object
  my $xml = new XML::Simple( NoAttr => 1,
                             SuppressEmpty => 1,
                             XMLDecl => 1 ,
                             RootName=>'CallData');

  my $result = $xml->XMLout($hashref);
  print $result;
}

writexmlout();

意外结果

<?xml version='1.0' standalone='yes'?>
<CallData>
  <CallStates>
    <name>CallStatesSPR</name>
    <Name>Acknowledged</Name>
  </CallStates>
  <Calls>
    <CHD>
      <Email>ron.rich@mavenir.com</Email>
      <FirstName>Ron</FirstName>
      <LastName>Rich</LastName>
      <Sign>B2B</Sign>
      <Tel>(123)  456-4567</Tel>
    </CHD>
    <CustCallID>6199999</CustCallID>
    <Remarks>Ticket successfully Ebonded</Remarks>
    <SPCallID>12</SPCallID>
  </Calls>
  <ContractElements>
    <ShortName>test</ShortName>
  </ContractElements>
  <Contracts>
    <ShortName>123231123</ShortName>
  </Contracts>
</CallData>

期望的结果

<?xml version='1.0' standalone='yes'?>
<CallData>
 <CallStates>
    <CallStatesSPR>
     <Name>Acknowledged</Name>
    </CallStatesSPR>
  </CallStates>
  <Calls>
    <CHD>
      <Email>ron.rich@mavenir.com</Email>
      <FirstName>Ron</FirstName>
      <LastName>Rich</LastName>
      <Sign>B2B</Sign>
      <Tel>(123)  456-4567</Tel>
    </CHD>
    <CustCallID>6199999</CustCallID>
    <Remarks>Ticket successfully Ebonded</Remarks>
    <SPCallID>12</SPCallID>
  </Calls>
  <ContractElements>
    <ShortName>test</ShortName>
  </ContractElements>
  <Contracts>
    <ShortName>123231123</ShortName>
  </Contracts>
</CallData>

为什么会这样?为什么标签“名称”出现在我不期待的位置?

3 个答案:

答案 0 :(得分:4)

执行此操作的正确方法是完全禁用属性折叠。之前的答案之所以有效,只是因为它们限制了数组折叠到源中无处存在的属性。由于您的XML根本没有属性,因此您应该使用

KeyAttr设置为空列表
KeyAttr => {},

正确生成输出

<CallStates>
  <CallStatesSPR>
    <Name>Acknowledged</Name>
  </CallStatesSPR>
</CallStates>

我可以补充一点,我认为XML::Simple可能是一个糟糕的选择,这不太可能是你最后的问题。如果你开始失去耐心,请考虑XML::DOMXML::LibXML

答案 1 :(得分:0)

您需要使用KeyAttr选项:

 my $result = $xml->XMLout($hashref,KeyAttr=>{item=>"CallStatesSPR"});

我对XML::Simple并不是非常有经验,但是根据我可以收集的内容,此选项告诉解析器您要将CallStatesSPR视为项目并将结果哈希引用放入<CallStatesSPR>个标签。

答案 2 :(得分:0)

KeyAttr =>选项允许您指定要作为主键的项目名称。例如,您需要KeyAttr => { CallStatesSPR => 'name'}