我在perl中使用XML::Bare模块。
我的xml类似于:
<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属性值,而不是子节点。当属性和子名相同时,请任何人帮助我处理这些情况。
谢谢
发布于 2014-06-19 17:14:49
如果使用XML::Bare或XML::Simple,它们应该仅限于最基本的XML读取。如果您的数据有一个属性和共享名称的子节点,那么这个限制就会失败。
然而,实际上,除非有特定的理由不这样做,否则我们应该坚持使用更现代的XML解析器,比如XML::Twig和XML::LibXML,以及XPath支持的全部功能。
下面使用这两个模块来解析XML:
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>产出:
XML::LibXML
10
20
XML::Twig
10
20发布于 2014-06-19 15:25:45
它看起来像XML::Bare中的一个bug。我没有在<num>输出中看到Dumper元素:
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的解决方案
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 20https://stackoverflow.com/questions/24309964
复制相似问题