Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

How to write an xpath query including attributes for an XML with namespace

by topola1882 (Initiate)
on Sep 06, 2013 at 12:42 UTC ( #1052705=perlquestion: print w/replies, xml ) Need Help??

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

Hello everybody, i think i have a simple question but i can't find an aswer to it anywhere so i hope you can help.
I have an xml file with namespace and i want to select a node with an attribute with a specific value. Here is the xml file:

<?xml version="1.0" encoding="UTF-8"?> <guestbook xmlns="" xmlns:xs=" +MLSchema-instance" nome="740" xs:schemaLocation=" gue +stbook.xsd"> <comment confermato="true" timestamp="20130627112554"> <guest>...</guest> </comment> <comment confermato="false" timestamp="20130903225513"> <guest>...</guest> </comment> <comment confermato="false" timestamp="20130904191337"> <guest>...</guest> </comment> </guestbook>

I need, with a cgi script, to select the node "comment" with the timestamp "20130903225513". The problem is that i don't know hot to put the namespace correctly. Here is the code for the script

#!/usr/bin/perl use strict; use XML::LibXML; use HTML::Entities; use CGI; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use Fcntl qw(:flock); my $cgi = new CGI; print "Content-type: text/html\n\n"; my $file_dati = "../data/xml/guestbook_xml.xml"; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($file_dati) || die("dead1"); my $root = $doc->getDocumentElement || die("dead2"); my $nodetobefound= "xs:commento[xs:\@timestamp='20130903225513']"; print "$nodetobefound\n"; my $commento = $root->findnodes("$nodetobefound") || die("dead3"); print $commento->get_node(0)->toString();

If i don't insert any namespace in the query i finish in the "dead3" die, if i put any kind of namespace i receive an "Xpath error: invalid expression".
Any hint on how to write the correct xpath query?
thanx in advance, Giulia

Replies are listed 'Best First'.
Re: How to write an xpath query including attributes for an XML with namespace
by choroba (Archbishop) on Sep 06, 2013 at 12:59 UTC
    To use a namespace in an XPath expression, you have to register it first. The following works for me:
    #!/usr/bin/perl use warnings; use strict; use XML::LibXML; my $file_dati = '/path/to/file.xml'; my $parser = 'XML::LibXML'->new(); my $doc = $parser->parse_file($file_dati) || die('dead1'); my $xc = 'XML::LibXML::XPathContext'->new($doc); $xc->registerNs('mw', ''); my $nodetobefound = '//mw:comment[@timestamp="20130903225513"]'; print "To be found: $nodetobefound\n"; my $commento = $xc->findnodes($nodetobefound) || die('dead3'); print $commento->get_node(0)->toString();

    As Corion suggested, I changed the name of the element and added // for recursive search.

    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Thanks Choroba, it worked!!

Re: How to write an xpath query including attributes for an XML with namespace
by Corion (Pope) on Sep 06, 2013 at 12:53 UTC

    You have no commento nodes in your XML. Maybe that's already the whole problem?

    Also, when trying XPath queries, I find it often more beneficial to use unanchored queries while trying things out. You may want to search for //comment instead of commento.

      thanks Corion, that was not the problem (i just copied the wrong code). Anyway i resolved with the hint from Choroba

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1052705]
Approved by Old_Gray_Bear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2021-06-21 06:05 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (98 votes). Check out past polls.