我在http://www.perlmonks.org/?node_id=606909
上找到了这个以合格的名字查找...
在这种情况下,您可以在任何节点上调用findnodes方法,您不需要XML :: LibXML :: XPathContext及其前缀=>名称空间映射 $ doc-> findnodes('// / info / fooTransaction / transactionDetail / [name()=“histFile:transactionSummary”] / *');
我必须编辑我的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;
}
答案 0 :(得分:1)
遵循文章中给出的相同模型。如果要测试节点的文本名称,而不是考虑节点的命名空间映射到的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"]