У меня есть следующий файл XML

<root>
  <test name="test1">
    <node name="node1">
    </node>
    <child type="" line="321" name="">
      <grandChild name="WM">
        ....
      </grandChild>
    </child>
  </test>
  <test name="test2">
    <node name="node2">
    </node>
    <child type="" line="123" name="">
      <grandChild name="WM">
        ....
      </grandChild>
    </child>
  </test>
</root>

Я хочу получить доступ к некоторым узлам, если условие выполняется, но мне не удается получить дочерние элементы <grandChild>.

Мой код Perl выглядит следующим образом

my $xml = XML::LibXML::XPathContext->new();

my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(sr => 'http://www.froglogic.com/XML2');

my $tree         = $parser->parse_file($xmlFile);
my $nodes        = $xml->findnodes("//sr:root/sr:test[$attribute]", $tree);
my $childTagName = 'child';

foreach my $node ( $nodes->get_nodelist ) {

    my $childNodes = $node->getChildNodes();

    foreach my $childNode ( $childNodes->get_nodelist ) {

        if ( $childNode->getName() eq $childTagName ) {

            my $newresults = $childNode->findnodes('//child');
        }
    }
}

Конечно, основная его часть удалена, чтобы упростить мой вопрос.

Я должен упомянуть, что $attribute - это имена тестов (test1, test2, ....).

Не могли бы вы сообщить мне, почему я не могу получить внука в $newresults, а он всегда пуст, когда я печатаю в командной консоли.

0
Royeh 18 Июн 2018 в 10:15

1 ответ

Лучший ответ

Ваш код не работает. Откуда взялся $attribute? Кроме того, вы не показываете определение пространства имен sr в XML, поэтому трудно догадаться, в чем проблема, но я предполагаю, что child также принадлежит пространству имен. В этом случае вам также необходимо использовать префикс для этого и использовать контекст XPath для его поиска. Кроме того, используйте XPath для указания условий вместо перебора дочерних узлов:

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use XML::LibXML;

my $tree = 'XML::LibXML'->load_xml(IO => *DATA);
my $xpc = 'XML::LibXML::XPathContext'->new($tree);
$xpc->registerNs(sr => 'http://sr');

my $attribute = '@name';
my $test_nodes = $xpc->findnodes("/sr:root/sr:test[$attribute]");
for my $test_node (@$test_nodes) {
    for my $child_node ($xpc->findnodes('sr:child', $test_node)) {
        my $newresults = $xpc->findnodes('sr:grandChild', $child_node);
        say join ' ',
            $test_node->{name},
            $child_node->{line},
            $_->{name}
            for @$newresults;
    }
}

__DATA__
<root xmlns='http://sr'>
    <test name="test1">
        <node name="node1">

        </node>
        <child type="" line="321" name="">
            <grandChild name="WM">
                ....
            </grandChild>
        </child>

    </test>
    <test name="test2">
        <node name="node2">

        </node>
        <child type="" line="123" name="">
            <grandChild name="WM">
                ....
            </grandChild>
        </child>
    </test>
</root>
3
choroba 18 Июн 2018 в 07:37