Как мне написать XPath с определенным именем с помощью Perl XML :: LibXML? - PullRequest
2 голосов
/ 21 апреля 2010

Я нашел это на http://www.perlmonks.org/?node_id=606909

ищет по имени ...
В этом случае вы можете вызвать метод findnodes на любом узле, вам не нужен XML :: LibXML :: XPathContext с его префиксом => отображением пространства имен: $ doc-> findnodes ('// / info / fooTransaction / TransactionsDetail / [name () = "histFile :actionSummary"] / *');

Каким образом мне нужно отредактировать xpath, чтобы мой скрипт работал без XPathContext?

#!/usr/bin/env perl
use warnings; use strict;
use 5.012;
use XML::LibXML;


my $parser = XML::LibXML->new;
$parser->recover_silently( 1 );

my $doc = $parser->parse_file( 'http://www.heise.de/' );

my $xc = XML::LibXML::XPathContext->new( $doc->getDocumentElement );
$xc->registerNs( 'xmlns', 'http://www.w3.org/1999/xhtml' );

my $nodes = $xc->findnodes( '//xmlns:h2/xmlns:a' );
for my $node ( $nodes->get_nodelist ) {
    say $_->getName, '=', $_->getValue for $node->attributes;
}

1 Ответ

1 голос
/ 21 апреля 2010

Следуйте той же модели, что и в статье. Если вы хотите проверить текстовое имя узла, вместо рассмотрения того, на какой URI отображается пространство имен узла, вызовите name и выполните сравнение строк.

//*[name() = "xmlns:h2"]/*[name() = "xmlns:a"]

Однако для того, чтобы это выражение соответствовало чему-либо, в документе должны быть узлы с буквальным названием xmlns:h2. Вам нужно иметь такой документ:

<xmlns:h2>
  <xmlns:a>header</xmlns:a>
</xmlns:h2>

Однако страница, на которую вы ссылались, выглядит не так. Он использует обычные имена узлов HTML, такие как h2 и a, а не xmlns:h2. Простые имена действительно находятся в пространстве имен xmlns, но только потому, что они настроены как пространство имен по умолчанию для документа. Поскольку узлы не имеют имен с префиксом пространства имен, не включайте этот префикс в строки имен:

//*[name() = "h2"]/*[name() = "a"]

Еще одно изменение, которое вы можете внести в случае, если некоторые узлы используют префикс xmlns, а другие - нет, это использовать local-name вместо name; тогда он удалит любой существующий префикс пространства имен.

//*[local-name() = "h2"]/*[local-name() = "a"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...