开发者

What is the correct way to parse XML using XML::TreeBuilder

I need to parse following 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>

There is two child "entity" elements in "response" element.

But following code will return 3 "entity" elements:

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";
}

This code returns also "entity" element that is child of "link" element.

But I need to get only "entity" elements that are childs of "response" element.

What is the correct way to do it?

Something like this?

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";
   }
}

Is this appoach good?


lineage_tag_names() (refer HTML::Element's documentation) will return a list of ancestors of an element. The 0th ancestor is the parent.

Program

#!/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>

Output

<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>
__________________________________________________
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜