weismat has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use XML::LibXML with an XPath query. I have created the query using Sketchpath (http://pgfearo.googlepages.com/) which allows to create XPath queries on the fly. (I have used it mainly with C# before). I use the following code for trying to query the document according to a turorial on perlmonks.
my $parser=XML::LibXML->new(); my $doc=$parser->parse_file($file); foreach my $node($doc->findnodes($xpathQuery));
This fails as no nodes are found. When manually walking through the tree I see that the namespace using $doc->firstChild->nameSpaceURI. How do I add the found name space, so that the XPATH query gives the wanted result - I guess that Sketchpath handles this automatically. The XML look like this <?xml version="1.0" encoding ="UTF-8"?><xxx xmlns="http://xxx><yyy>zzz</yyy></xxx> The query is a simple /xxx/yyy (sorry - missed this when simplyfying the xml.

Replies are listed 'Best First'.
Re: XML::Lib XML question
by ikegami (Pope) on Oct 22, 2009 at 08:31 UTC

    Regarding your update...

    The query is a simple /yyy

    There is no {}yyy element at the root (or anywhere else in your XML document), so LibXML is correct in returning nothing.

    You want to match the {http://xxx}yyy element, so you need to use

    my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($file_name); my $root = $doc->documentElement(); my $xpc = XML::LibXML::XPathContext->new(); $xpc->registerNs( xxx => 'http://xxx' ); for my $node ( $xpc->findnodes('/xxx:xxx/xxx:yyy', $root) ) { ... }

    As I mentioned earlier, this is documented in XML::LibXML::Node, under findnodes, under "NOTE ON NAMESPACES AND XPATH".

    "xxx" can be replaced with any identifier you wish, as long as you use what you pass to registerNS in your queries.

    Update: I had forgotten the include the root node in the XPath. Fixed.

      It works now - thanks a million. I will add a reference to this node into the tutorial - I guess I am not the only one falling into this pitfall.
Re: XML::Lib XML question
by ikegami (Pope) on Oct 22, 2009 at 08:23 UTC
    I directed you to post this node because your query is wrong and the CB doesn't lend itself to giving us the info we need to fix your broken query. However, you didn't give any info that would help us do so.
Re: XML::Lib XML question
by Corion (Pope) on Oct 22, 2009 at 08:27 UTC

    As far as I understand XPath, /yyy will look for a root node of <yyy>, which you don't have. Either /xxx/yyy or //yyy should find the yyy node.

    Update: This just shows what little I know of namespaces. I think ikegami's reply is correct and this one is wrong. With a root node of xxx, $root->findNodes should find /yyy in <xxx><yyy></xxx>, but the namespace prevents the match.

      The beauty of Sketchpath is that you click on the node and it suggests the query.