使用XML :: TreeBuilder解析XML的正确方法是什么

时间:2010-12-02 11:16:01

标签: xml perl

我需要解析以下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";
   }
}

这个方法好吗?

1 个答案:

答案 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>
__________________________________________________