in reply to XML namespace question

Thanks everyone for your insightful (and entertaining?) comments - yes, this is the OP, but being new I may have contravened best practice for changing my username (my apologies to the gods, and other fellow monks). The suggested solutions were all very helpful in understanding the nuances of namespaces (no namespace vs. default namespace and so on) and the multiple ways to come at this sort of problem. I have a further question now with regard to attributes. Whats the best method to pull out the value of a given attribute (like junos:style="terse" in the vlan-information element), especially when the attribute is in a different namespace as the containing element. Using the same XML snippet as in the original post:

my $dom = XML::LibXML->load_xml( string => $jnx->{'server_response'}, # parser options ... ); my $xpc = XML::LibXML::XPathContext->new(); $xpc->registerNs('nc', 'urn:ietf:params:xml:ns:netconf:base:1.0'); $xpc->registerNs('j', 'http://xml.juniper.net/junos/12.3R9/junos'); my @nodes = $xpc->findnodes( "/nc:rpc-reply/nc:vlan-information", $dom +); foreach my $node (@nodes){ print "\nAttempt 1\n"; my $attr_style = $node->findvalue('/@style'); $attr_style ? print "Got Attr _style_: $attr_style\n" : print "Cou +ldn't find Attr _style_\n"; print "\nAttempt 2\n"; my $test1 = $node->hasAttributes(); print " Yes I have attribute(s)\n" if $test1; print "\nAttempt 3\n"; my @attrs = $node->attributes('/style'); foreach my $attr (@attrs){ print "here's an attribute: $attr->to_literal\n"; } print "\nAttempt 4\n"; my $attrnode = $node->getAttributeNodeNS( 'http://xml.juniper.net/ +junos/12.3R9/junos', 'style'); print "here's an attribute: $attrnode\n"; }

My attempts above (the last two at least) yield a result but its not ideal... I want to say for attribute "style" in namespace "junos", what is the value? Thanks!

Replies are listed 'Best First'.
Re^2: XML namespace question
by Anonymous Monk on Oct 13, 2015 at 23:48 UTC
    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; use XML::LibXML 1.70; ## for load_html/load_xml/location sub XML::LibXML::Node::F { my $self = shift; my $xpath = shift; my %prefix = @_; our $XPATHCONTEXT; $XPATHCONTEXT ||= XML::LibXML::XPathContext->new(); while( my( $p, $u ) = each %prefix ){ $XPATHCONTEXT->registerNs( $p, $u ); } $XPATHCONTEXT->findnodes( $xpath, $self ); } my $doc = XML::LibXML->new()->parse_string(q{<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.3R9/junos"> <vlan-information junos:style="terse"> <vlan-terse/> <vlan> ... </vlan> </vlan-information> </rpc-reply> }); ## "registration" find a node that don't exist $doc->F( "/NOTExIST", 'nc', 'urn:ietf:params:xml:ns:netconf:base:1.0', 'j', 'http://xml.juniper.net/junos/12.3R9/junos', ); for my $vlaninfo( $doc->F( "/nc:rpc-reply/nc:vlan-information", ) ){ my( $style ) = $vlaninfo->F('./@j:style'); print "$style\n"; dd( { %$vlaninfo }); } __END__ junos:style="terse" { "{http://xml.juniper.net/junos/12.3R9/junos}style" => "terse" }