Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

XML::Lib XML question

by weismat (Friar)
on Oct 22, 2009 at 08:16 UTC ( #802684=perlquestion: print w/replies, xml ) Need Help??
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 ( 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.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://802684]
Approved by Old_Gray_Bear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2018-06-21 09:09 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (117 votes). Check out past polls.