Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

How do you get attribute values using XML::LibXML

by onegative (Scribe)
on Dec 14, 2010 at 21:37 UTC ( [id://877166]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to extract the attribute value of name but not sure what/how I am suppose to do so...can't find an actual real example.
Can someone help point me in the right direction?
Many Thanks..
file.xml
<HOSTNAME name='apple'> <PATROL> <ACL> <USERNAME name='ml3007'> <HOST>*</HOST> <PERMISSION>COPS</PERMISSION> </USERNAME> </ACL> </PATROL> </HOSTNAME>


use strict; use warnings; use XML::LibXML; my $filename = $ARGV[0]; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($filename); my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() ); foreach my $sections ($xc->findnodes('/HOSTNAME/PATROL/ACL/USERNAME' +)) { my($username) = $sections->getAttribute('name'); my($permissions) = $sections->findnodes('./PERMISSION'); my($host) = $sections->findnodes('./HOST'); print $username->to_literal, "\n"; print $permissions->to_literal, "\n"; print $host->to_literal, "\n"; }

Replies are listed 'Best First'.
Re: How do you get attribute values using XML::LibXML
by PeterPeiGuo (Hermit) on Dec 15, 2010 at 01:11 UTC

    Take away that "->to_literal()" method call after $username:

    print $username, "\n"; print $permissions->to_literal, "\n"; print $host->to_literal(), "\n";

    Peter (Guo) Pei

Re: How do you get attribute values using XML::LibXML
by tofanikanudo (Initiate) on Dec 15, 2010 at 13:57 UTC

    Hi,
    Method findnodes of XML::LibXML::XPathContext will return an array of elements or a XML::LibXML::NodeList object in case of scalar context.

    So In above case, variable $section is a object of XML::LibXML::Element. Method getAttribute will return a scalar value if element has value of specified attribute.

    So in above example $username has string value, not an element.

    Thanks
    Dhaval Patel

Re: How do you get attribute values using XML::LibXML
by grantm (Parson) on Dec 16, 2010 at 20:30 UTC

    In the case where your XPath query will find only one node (e.g.: when referring to an attribute), instead of using findnodes, you could the findvalue method to get the text content of the matching node:

    #!/usr/bin/perl use strict; use warnings; use XML::LibXML; my $filename = $ARGV[0]; my $parser = XML::LibXML->new(); my $doc = $parser->parse_file($filename); my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() ); foreach my $sections ($xc->findnodes('/HOSTNAME/PATROL/ACL/USERNAME')) + { my $username = $sections->findvalue('./@name'); my $permissions = $sections->findvalue('./PERMISSION'); my $host = $sections->findvalue('./HOST'); print "$username\n"; print "$permissions\n"; print "$host\n"; }

    Also, if your document doesn't actually use namespaces (which your example doesn't) then you might as well leave out XML::LibXML::XPathContext and call $doc->findnodes instead.

    However if your document does use namespaces then instead of doing this:

    $sections->findnodes('./PERMISSION');

    You need to do this for the namespace prefixes to work:

    $xc->findnodes('./PERMISSION', $sections);
Re: How do you get attribute values using XML::LibXML
by ikegami (Patriarch) on Dec 16, 2010 at 21:00 UTC

    In addition to what's been said, it makes no sense to use an xpc in one place and not the other.

    my $xc = XML::LibXML::XPathContext->new($root); $xc->findnodes('/HOSTNAME/PATROL/ACL/USERNAME') $sections->findnodes('./PERMISSION')

    should be

    $root->findnodes('/HOSTNAME/PATROL/ACL/USERNAME') $sections->findnodes('./PERMISSION')

    or

    my $xc = XML::LibXML::XPathContext->new( $root ); $xc->findnodes('/HOSTNAME/PATROL/ACL/USERNAME') $xc->findnodes('./PERMISSION', $sections)

    An xpc isn't needed here since your XML doesn't use namespaces, but there's no harm in using one. Just be consistent about it.

    Note that the leading to "./" is useless (whether an xpc is used or not). The following will do:

    $xc->findnodes('PERMISSION', $section)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://877166]
Approved by planetscape
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2025-06-24 16:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.