我需要解析以下XML:
<response>
<entity id="1">
<exists>Y</exists>
</entity>
<entity id="2">
<exists>Y</exists>
<attributes>
<attribute name="User">root</attribute>
</attributes>
<links>
<link type="hard">
<entity id="1"/>
</link>
</links>
</entity>
</response>
“response”元素中有两个子“entity”元素 但是下面的代码将返回3个“实体”元素:
my $tree = XML::TreeBuilder->new();
$tree->parse($responseXML);
my $response = $tree->find_by_tag_name('response');
foreach my $entity ($response->find_by_tag_name('entity'))
{
print "$entity\n";
}
此代码还返回“entity”元素,它是“link”元素的子元素 但我只需要获得“实体”元素,这些元素是“响应”元素的子元素 这样做的正确方法是什么? 像这样的东西?
my @elements = $response->content_list();
foreach my $element (@elements)
{
if (ref($element) && $element->tag() eq "entity")
{
#process entity element
my $id = $element->attr("id");
print "Entity id=$id\n";
}
}
这个方法好吗?
答案 0 :(得分:2)
lineage_tag_names()
(请参阅HTML::Element
的文档)将返回元素的祖先列表。第0个祖先是父母。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::TreeBuilder;
my $tree = XML::TreeBuilder->new();
$tree->parse( \*DATA );
my $response = $tree->find_by_tag_name('response');
for my $entity ( $response->find_by_tag_name('entity') ) {
my $immediate_parent = ( $entity->lineage_tag_names() )[0];
if ( $immediate_parent eq 'response' ) {
print $entity->as_XML();
print '_' x 50, "\n";
}
}
__DATA__
<response>
<entity id="1">
<exists>Y</exists>
</entity>
<entity id="2">
<exists>Y</exists>
<attributes>
<attribute name="User">root</attribute>
</attributes>
<links>
<link type="hard">
<entity id="1"/>
</link>
</links>
</entity>
</response>
<entity id="1">
<exists>Y</exists>
</entity>
__________________________________________________
<entity id="2">
<exists>Y</exists>
<attributes>
<attribute name="User">root</attribute>
</attributes>
<links>
<link type="hard">
<entity id="1"></entity>
</link>
</links>
</entity>
__________________________________________________