Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

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="http://myweb.com" xmlns:xs="http://www.w3.org/2001/X +MLSchema-instance" nome="740" xs:schemaLocation="http://myweb.com 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

Comment on How to write an xpath query including attributes for an XML with namespace
Select or Download Code
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

Re: How to write an xpath query including attributes for an XML with namespace
by choroba (Abbot) 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', 'http://myweb.com'); 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!!

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (7)
As of 2014-11-28 11:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (196 votes), past polls