How do I write a qualified name XPath with Perl XML :: LibXML?

I found this at http://www.perlmonks.org/?node_id=606909

looking at the qualified name ...
In this case, you can call the findnodes method on any node, you don't need XML :: LibXML :: XPathContext with its prefix => namespace mapping: $ doc-> findnodes ('/// info / fooTransaction / transactionDetail / [name () = "histFile: transactionSummary"] / * ');

In which direction do I need to change my xpath to get my script to work without 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;
}

      

+2


a source to share


1 answer


Follow the same model as in the article. If you want to test the textual name of a node, instead of looking at which URI the node namespace is in, then call name

and do a string comparison.

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

For this expression to match anything, however, there must be literal nodes in the document xmlns:h2

. You will need to have a document like this:

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

      



The page you're linked to doesn't look like it. It uses regular HTML node names like h2

and a

, not xmlns:h2

. Simple names are indeed in the namespace xmlns

, but only because they are configured as the default namespace for the document. Since nodes do not have a name with a namespace prefix, do not include this prefix in your names:

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

A further change you could make, in case some nodes use the prefix xmlns

when others don't, should be used local-name

instead name

; then it will strip the namespace prefix that is present.

// * [local-name () = "h2"] / * [local-name () = "a"]
+1


a source







All Articles