【问题标题】:Parsing nested XML using XMLin使用 XMLin 解析嵌套的 XML
【发布时间】:2015-07-28 16:14:33
【问题描述】:

我花了几个小时试图弄清楚如何使用 XMLin 来理解这个嵌套的 XML,但没有成功。我也试过这个网站上的例子;如何获得传递的 lca-data 并迭代前缀?

Dumper 输出在这里:http://pastebin.com/a4N8AtX1

简单代码:

$url = "http://www.localcallingguide.com/xmllocalprefix.php?npa=514&nxx=307";
$xml = new XML::Simple;
$data = $xml->XMLin(&getURL($url), ForceArray => [qw( lca-data prefix )]);

print Dumper( $data );

foreach $e (@{$data->{prefix}}) {
  print STDERR $e->{npa} . "\n";
}

没有输出...

提前致谢

【问题讨论】:

  • 没有$data->{prefix}——你可能希望$data->{lca-data}[0]{prefix}在你的foreach中。
  • 它确实有道理,但它也不会以这种方式进入循环
  • 哎呀;连字符不是有效的标识符字符,因此您必须使用引号:$data->{'lca-data'}[0]{prefix}use warnings; use strict; 可能会有所帮助。
  • 万岁 :) 谢谢!!它适用于引号:$data->{'lca-data'}[0]{'prefix'}

标签: xml perl parsing nested


【解决方案1】:

首先 - 真的 - 阅读 XML::Simple 的联机帮助页。特别注意上面写着的那句话:

不鼓励在新代码中使用此模块。其他模块也可以提供更直接和一致的接口。

另外——不要在子例程调用前使用&——它们通常是个坏主意——使用它们有一些非常具体的原因,这不是一个原因。

而且您应该始终使用strictwarnings,尤其是在发布代码供他人查看时。

鉴于您的任务似乎是将每个 npa 元素输出到 STDERR 我建议您可以这样处理它 - 使用 XML::Twig 而不是 XML::Simple

#!/usr/bin/local/perl
use warnings;
use strict;

use LWP::Simple;
use XML::Twig;

my $url =
    'http://www.localcallingguide.com/xmllocalprefix.php?npa=514&nxx=307';

my $twig = XML::Twig->new(
    'twig_handlers' => {
        'npa' => sub { print STDERR $_->text, "\n"; }
    }
);
$twig->parse( get($url) );

在每个 npa 子元素上设置一个处理程序来“触发”并打印它 - 它在解析您的 XML 时执行此操作,这意味着您可以做一些非常巧妙的技巧,例如在解析时修改它(例如删除或移动元素)。

如果您希望简单地迭代一个元素,那么您可以这样做 - 这样做的好处是不使用大量内存,因为 XML 可以。 (XML::Twig 有 purge 可以让您丢弃任何已处理的 XML)。

否则,有 'children' 或 'get_xpath' 选项:

my $twig = XML::Twig->new()->parse( get($url) );
foreach
    my $prefix ( $twig->root->first_child('lca-data')->children('prefix') )
{
    print $prefix ->first_child_text('npa'), "\n";
}

### alternatively:

foreach my $prefix ( $twig->root->get_xpath('./lca-data/prefix') ) {
    print $prefix ->first_child_text('npa'), "\n";
}

如果您想使用子程序来处理和清除,您可以这样做:

sub process_prefix {
    my ( $twig, $prefix ) = @_;
    print $prefix ->first_child_text('npa'), "\n";
    $twig->purge;    #clears already parsed data - good if your XML is large!
}

my $url =
    'http://www.localcallingguide.com/xmllocalprefix.php?npa=514&nxx=307';

my $twig =
    XML::Twig->new( 'twig_handlers' => { 'prefix' => \&process_prefix } )
    ->parse( get($url) );

使用解析器进行 XML 解析做得很好。但是看看XML::TwigXML::LibXML 而不是XML::Simple - 它们都是更好的工作工具。 (XML::Twig 甚至有 simpify 方法......如果你真的需要它来实现向后兼容性,它几乎可以复制 XML::Simple

但您提出的问题的解决方案是:

foreach $e (@{ $data->{'lca-data'}[0]{'prefix'} } {

【讨论】:

  • Jim 已经给出了答案,但感谢所有细节和 Twig 参考,我一定会看看它。干杯
猜你喜欢
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多