Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: XML::LibXML and namespaces

by Lotus1 (Curate)
on Nov 09, 2012 at 13:29 UTC ( #1003124=note: print w/replies, xml ) Need Help??

in reply to XML::LibXML and namespaces

You can also give a relative path to the node in findvalue. The '.' means the current node so if "Time" is a child of the node at $node :

for my $node ($xml->findnodes('//y:Trackpoint')) { $time = $node->findvalue("./Time"); push @X,$time; }

If there are more than one "Time" nodes under $node then findvalue() will concatenate the text from all and return it.

Replies are listed 'Best First'.
Re^2: XML::LibXML and namespaces
by Anonymous Monk on Nov 11, 2012 at 13:33 UTC
    Wouldn't you know it :) xpath allows ignoring namespaces by using functions name and local-name, and the current node (.) comes in handy , heady even
    #!/usr/bin/perl -- use strict; use warnings; use XML::LibXML; my $doc = XML::LibXML->new()->parse_string( q{<?xml version='1.0' ?> <roshambo xmlns=""> <sham> <bo name="40" /> <bo name="2" /> </sham> <sham xmlns:ftt=""> <ftt:bo name="forty" /> <ftt:bo name="two" /> </sham> </roshambo> } ); for my $name ( $doc->findnodes( q{//*[local-name()="bo"]/@name} ) ) { printf "%-25s %s\n", $name->nodePath, $name->nodeValue; } print "\n\n"; for my $node ( $doc->findnodes( q{//*[name()="sham"]} ) ) { print "@{[ $node->nodePath ]}\n"; ## any children ## ./* ## any descendants ## .//* ## anywhere ## //* for my $name ( $node->findnodes( q{./*[local-name()="bo"]/@name} ) + ) { printf "%-25s %s\n", $name->nodePath, $name->nodeValue; } print "\n\n"; } __END__ /*/*[1]/*[1]/@name 40 /*/*[1]/*[2]/@name 2 /*/*[2]/ftt:bo[1]/@name forty /*/*[2]/ftt:bo[2]/@name two /*/*[1] /*/*[1]/*[1]/@name 40 /*/*[1]/*[2]/@name 2 /*/*[2] /*/*[2]/ftt:bo[1]/@name forty /*/*[2]/ftt:bo[2]/@name two
      Awesome! Exactly what I needed.
      I'm getting myself hopelessly confused with something similar. My XML looks like this:
      <user> <address name="1"> <entry name="Address line 1">street</entry> <entry name="Address line 2">suburb</entry> <entry name="Postal code">code</entry> </address> <address name="2"> <entry name="Address line 1">street2</entry> <entry name="Address line 2">suburb2</entry> <entry name="Postal code">code2</entry> </address> </user>
      How can I retrieve suburb2 from that? says
        /*[ local-name() = "user" and position() = 1 ] /*[ local-name() = "address" and position() = 2 and @name = "2" ] /*[ local-name() = "entry" and @name = "Address line 2" and contains(string(), "suburb2") ]
        So maybe you use
        /*[ local-name() = "user" ] /*[ local-name() = "address" ] /*[ local-name() = "entry" and @name = "Address line 2" ]
        or any number of things like that
        //entry[ @name = "Address line 2" ]
Re^2: XML::LibXML and namespaces
by Anonymous Monk on Nov 09, 2012 at 13:47 UTC
    that won't work if namespaces are in play, you have to use XPathContext

      Thanks, that's good to know. I haven't dealt with namespaces yet.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1003124]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2017-05-27 21:41 GMT
Find Nodes?
    Voting Booth?