假设我有一个XML文档示例,
<root>
<subnode1 att1="sn1att1" att2="sn1att2">Subnode 1</subnode1>
<subnode2 att1="sn2att1" att2="sn2att2">Subnode 2</subnode2>
<subnode3 att1="sn3att1" att2="sn3att2">
<subnode31 att1="sn31att1" att2="sn31att2">
<subnode311 att1="sn311att1" att2="sn311att2">
<subnode3111 att1="sn3111att1" att2="sn3111att2">Subnode 3-111</subnode3111>
</subnode311>
</subnode31>
<subnode32 att1="sn32att1" att2="sn32att2">Subnode 3-2</subnode32>
</subnode3>
</root>我想印这样的东西
sn1att1 sn1att2 Subnode 1
sn2att1 sn2att2 Subnode 2
sn3att1 sn3att2
sn31att1 sn31att2
sn311att1 sn311att2
sn3111att1 sn3111att2 Subnode 3-111
sn32att1 sn32att2 Subnode 3-2我编写了下面的代码,它能够打印所描述的属性,但无法打印标记值(例如"Subnode 1“、"Subnode 2”等)。
use XML::XPath;
use XML::XPath::XMLParser;
my $xp = XML::XPath->new( filename => 'raw1.xml' );
for my $node ( $xp->findnodes('*/*') ) {
print "\n" . $node->getName . "\t";
for my $attribute ( $node->getAttributes ) {
print " " . $attribute->getData;
}
for my $property ( $node->findnodes('.//*') ) {
print "\n" . $property->getName . "\t";
for my $attributes ( $property->getAttributes ) {
print " " . $attributes->getData;
}
}
}发布于 2016-07-08 13:25:29
我觉得这能做你想要的
我对XML::XPath不太熟悉,但我认识XPath
看起来,对于XML中的每个元素,您希望打印一行,其中包含每个属性的值,如果有,则打印所有子文本节点的值。
这并不像看上去那么简单,因为任何元素都可能包含多个文本子元素,其中散布着多个子元素。
此代码将所有属性和所有非空白文本的值累加到数组@line中,如果结果不是空的,则打印行。
我不明白为什么您所需的输出不包括我的行
sn32att1 sn32att2 Subnode 3-2也许你会解释?
use strict;
use warnings 'all';
use XML::XPath;
my $xp = XML::XPath->new( filename => 'raw1.xml' );
# for all elements in the data
#
for my $node ( $xp->findnodes('//*') ) {
my @line;
# all the attributes of this element
#
for my $attr ( $node->getAttributes ) {
push @line, $attr->getData;
}
# and all the non-blank child text nodes of this element
#
for ( $node->findnodes('text()') ) {
my $text = $_->getData;
push @line, $text if $text =~ /\S/;
}
# print it if there's anything to print
#
print "@line\n" if @line;
}输出
sn1att1 sn1att2 Subnode 1
sn2att1 sn2att2 Subnode 2
sn3att1 sn3att2
sn31att1 sn31att2
sn311att1 sn311att2
sn3111att1 sn3111att2 Subnode 3-111
sn32att1 sn32att2 Subnode 3-2https://stackoverflow.com/questions/38266974
复制相似问题