【问题标题】:XML::Simple in Perl not detecting all elementsPerl 中的 XML::Simple 未检测到所有元素
【发布时间】:2012-01-15 08:18:21
【问题描述】:

我正在尝试使用 XML::Simple 在 Perl 中解析一些 XML。

XML 遵循以下格式:

   <result>
    <doc>
      <field name="title">Sample Title</field>
      <field name="content">Content 1</field>
      <field name="content">Content 2</field>
      .
      .
      .
      <field name="content">Content n</field>
    </doc>
   </result>

使用 XML::Simple 我尝试解析并打印标题和所有内容。问题是只打印了最后一个内容项。我决定使用 Dumper,这就是它返回的内容:

$VAR1= {
  'result'=> {  
           'doc' => [
                {
                  'field' => {                    
                                'content' => {
                                             'content' => 'Content n'
                                             },
                                'title' => {
                                             'content' => 'Sample Title'
                                           }
                                 }
                      }

每个文档元素只显示最后一个内容项。这有什么原因吗?我该怎么做才能让它检测到所有内容项?

编辑:这是代码:

my $url = "http://www.testurl.com/test.xml";
my $content = get $url;
die "Couldn't get XML" unless defined $content;

my $xml = new XML::Simple;
my $xmlData = $xml->XMLin($content);
print Dumper($xmlData); 

【问题讨论】:

  • 贴出相关代码。特别是 XML::Simple 实例的初始化和打印。
  • 好的,我已经添加了代码。内容是存储在内部通过 HTTP 访问的 XML 文件。
  • 所以testurl.com/test.xml 指向你的.xml 对吗?
  • 我的代码包含实际链接,是的。如果我这样做:打印 $content;整个 XML 文件都被打印出来了,所以获取文件没有问题。只有将它加载到 XML::Simple 中,我才会丢失除最后一个以外的所有内容字段。

标签: xml perl xml-parsing


【解决方案1】:

KeyAttr

use warnings;
use strict;
use XML::Simple;
use Data::Dumper;

$Data::Dumper::Sortkeys=1;

my $str = '
<result>
    <doc>
      <field name="title">Sample Title</field>
      <field name="content">Content 1</field>
      <field name="content">Content 2</field>
      <field name="content">Content n</field>
    </doc>
</result>
';

print Dumper(XMLin($str, KeyAttr => 'content'));

__END__

$VAR1 = {
          'doc' => {
                   'field' => {
                              'Content 1' => {
                                             'name' => 'content'
                                           },
                              'Content 2' => {
                                             'name' => 'content'
                                           },
                              'Content n' => {
                                             'name' => 'content'
                                           },
                              'Sample Title' => {
                                                'name' => 'title'
                                              }
                            }
                 }
        };

【讨论】:

    【解决方案2】:

    每个 POD:

    注意 1:'KeyAttr' 的默认值为 ['name', 'key', 'id']。如果您不想折叠输入或展开输出,则必须将此选项设置为空列表以禁用该功能。

    它将“名称”作为 ID 类型字段并将元素折叠在一起。

     perl -MXML::Simple -MData::Dumper
    
    my $raw = <<XML_SAMPLE;
     <result>
        <doc>
          <field name="title">Sample Title</field>
          <field name="content">Content 1</field>
          <field name="content">Content 2</field>
          .
          .
          .
          <field name="content">Content n</field>
        </doc>
       </result>
    XML_SAMPLE
    
    my $xml = new XML::Simple;
    my $xmlData = $xml->XMLin($raw, KeyAttr => []);
    print Dumper($xmlData);
    
    __END__
    $VAR1 = {
              'doc' => {
                       'content' => '
          .
          .
          .
          ',
                       'field' => [
                                  {
                                    'content' => 'Sample Title',
                                    'name' => 'title'
                                  },
                                  {
                                    'content' => 'Content 1',
                                    'name' => 'content'
                                  },
                                  {
                                    'content' => 'Content 2',
                                    'name' => 'content'
                                  },
                                  {
                                    'content' => 'Content n',
                                    'name' => 'content'
                                  }
                                ]
                     }
            };
    

    【讨论】:

    • 不用担心,我自己在整个夏天都花了一些时间来寻找这个 ;-)
    【解决方案3】:

    XML::Simple 将 name 视为重复 xml 元素的唯一标识符。尝试将您的“名称”属性切换为“标签”以进行测试。我希望您会看到您期望的转储程序输出。看一下 XML::Fast,我发现它更加一致,更不用说速度至少快了一个数量级。

    【讨论】:

    • 仅供参考 - 任何速度差异很可能是由于 XML::Simple 回退到 XML::SAX::PurePerl 解析器。安装 XML::SAX::Expat(XS) 会加快速度并修复一些解析错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2021-10-18
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多