Perl XML: DOM - Получение детей на определенной глубине - PullRequest
1 голос
/ 13 декабря 2010

Я делаю разбор XML с помощью Perl и выбрал XML :: DOM .Предположим, я анализирую файл, содержащий следующее:

<document>
   <A>
      <B/>
      <B/>
   </A>
   <B/>
</document>

Элемент "B" обрабатывается по-разному в зависимости от его относительного расположения в документе (т. Е. B, родительский элемент которого A отличается от B, чейродитель является документом).Из ссылки на узел документа можно получить B, которые являются непосредственными дочерними элементами.Затем, позже, получите ссылку на узел A, чтобы получить только дочерние узлы B?

Спасибо,

Andrew

Ответы [ 2 ]

4 голосов
/ 13 декабря 2010

Другой идеей было бы загрузить XML :: DOM :: XPath , что делает такие запросы довольно естественными и менее подробными.

B узлов, которые являются потомками элемента документа:

@nodes = $doc->findnodes('/document/B');

B-узлы, которые являются дочерними по отношению к A-узлам, которые являются дочерними по отношению к документу:

@nodes = $doc->findnodes('/document/A/B');

B-узлы, которые являются непосредственными потомками A-узлов, встречающихся где угодно:

@nodes = $doc->findnodes('//A/B');

B узлов, которые являются потомками любого узла A:

@nodes = $doc->findnodes('//A//B');

B узлов, у которых есть один (ровно один) предок между ними и документом:

@nodes = $doc->findnodes('/document/*/B');

И многое другое! (Я добавил много вариантов, потому что из вашего вопроса не ясно, какие именно являются наиболее подходящими для вашей проблемы).

Поскольку все значения являются просто обычными объектами XML :: DOM с добавлением некоторых методов, вы можете смешивать и сопоставлять их с любым существующим кодом XML :: DOM практически без суеты.

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

Предполагая, что вы знаете, что все элементы B будут дочерними элементами документа или A, вы можете использовать необязательный параметр recurse для getElementsByTagName .Передача 0 означает возврат только прямых дочерних элементов:

my @docB = $doc->getElementsByTagName('B', 0);
# do something with @docB

for my $aNode ($doc->getElementsByTagName('A')) {
  my @AB = $aNode->getElementsByTagName('B', 0);
  # do something with @AB
}
...