Как правильно проанализировать XML с помощью XML :: TreeBuilder? - PullRequest
0 голосов
/ 02 декабря 2010

Мне нужно проанализировать следующий 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";
}

Этот код также возвращает элемент «сущность», который является дочерним по отношению к элементу «ссылка».
Но мне нужно получить только элементы «сущность», которые являются потомками элемента «ответ».
Как правильно это сделать?
Что-то вроде этого?

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 Ответ

2 голосов
/ 02 декабря 2010

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>
__________________________________________________
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...