首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XML问题::Bare perl

XML问题::Bare perl
EN

Stack Overflow用户
提问于 2014-06-19 15:08:10
回答 2查看 255关注 0票数 0

我在perl中使用XML::Bare模块。

我的xml类似于:

代码语言:javascript
复制
<xml>
    <element num="1">
        <num>10</num>
    </element>
    <element num="2">
        <num>20</num>
    </element>
</xml>

我想提取出子<num>标记中包含的值。也就是说,我想要10 and 20作为输出。但是,当我使用$xml->{element}->[$i]->{num}->{value}获得值时,它返回1 adn 2,即返回num属性值,而不是子节点。当属性和子名相同时,请任何人帮助我处理这些情况。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-19 17:14:49

如果使用XML::BareXML::Simple,它们应该仅限于最基本的XML读取。如果您的数据有一个属性和共享名称的子节点,那么这个限制就会失败。

然而,实际上,除非有特定的理由不这样做,否则我们应该坚持使用更现代的XML解析器,比如XML::TwigXML::LibXML,以及XPath支持的全部功能。

下面使用这两个模块来解析XML:

代码语言:javascript
复制
use strict;
use warnings;

use XML::LibXML;
use XML::Twig;

my $data = do {local $/; <DATA>};

print "XML::LibXML\n";
my $xml = XML::LibXML->load_xml(string => $data);
for my $node ($xml->findnodes('//element/num')) {
    print $node->textContent(), "\n";
}

print "XML::Twig\n";
my $t = XML::Twig->new( 
    twig_handlers => {
        '//element/num' => sub { print $_->text(), "\n" },
    },
);
$t->parse( $data );

__DATA__
<xml>
    <element num="1">
        <num>10</num>
    </element>
    <element num="2">
        <num>20</num>
    </element>
</xml>

产出:

代码语言:javascript
复制
XML::LibXML
10
20
XML::Twig
10
20
票数 1
EN

Stack Overflow用户

发布于 2014-06-19 15:25:45

它看起来像XML::Bare中的一个bug。我没有在<num>输出中看到Dumper元素:

代码语言:javascript
复制
use warnings;
use strict;
use XML::Bare;

my $xml = q(
<xml>
    <element num="1">
        <num>10</num>
    </element>
    <element num="2">
        <num>20</num>
    </element>
</xml>
);

my $ob = new XML::Bare( text => $xml );
my $root = $ob->parse();

use Data::Dumper;
$Data::Dumper::Sortkeys=1;
print Dumper($root);

__END__

$VAR1 = {
          '_i' => 0,
          '_pos' => 0,
          '_z' => 0,
          'value' => '
',
          'xml' => {
                     '_i' => 438404290,
                     '_pos' => 1,
                     '_z' => 130,
                     'element' => [
                                    {
                                      '_i' => 438404300,
                                      '_pos' => 2,
                                      '_z' => 64,
                                      'num' => {
                                                 '_att' => 1,
                                                 'value' => '1'
                                               },
                                      'value' => '
        '
                                    },
                                    {
                                      '_i' => 438404359,
                                      '_pos' => 4,
                                      '_z' => 123,
                                      'num' => {
                                                 '_att' => 1,
                                                 'value' => '2'
                                               },
                                      'value' => '
        '
                                    }
                                  ],
                     'value' => '
    '
                   }
        };

你可以提交一个错误报告

下面是一个使用XML::Twig的解决方案

代码语言:javascript
复制
use warnings;
use strict;
use XML::Twig;

my $xml = q(
<xml>
    <element num="1">
        <num>10</num>
    </element>
    <element num="2">
        <num>20</num>
    </element>
</xml>
);

my $twig= XML::Twig->new(twig_handlers => { element => \&elem });
$twig->parse($xml);

sub elem {
    my( $twig, $ele)= @_;
    my $att = $ele->att('num');
    my $num = $ele->first_child('num')->text();
    print "$att $num\n";
}

__END__

1 10
2 20
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24309964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档