3

I want to retrieve attribute value, using xpath option (without using xmllint' shell).

my xml:

<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

this what I tried:

xmllint --xpath '//XML/*[local-name()='Elem']/@sn' FILE_1.xml
XPath set is empty

xmllint --xpath '//XML/*[local-name()='Elem' and namespace-uri()="http://www.w3.org/TR/html4/"]/@sn' FILE_1.xml
XPath set is empty

(I know I can use sed to strip away namespaces but I want to avoid that either)

4

Yes, don't use sed on XML. It's bad news.

I think your problem is actually a simple matter of quoting - you quote your xpath in single quotes, and Elem is also in single quotes.

I don't have a copy of xmllint handy, but this works:

#!/usr/env/perl

use strict;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML -> load_xml ( IO => \*DATA ); 
print $xml -> findnodes('//XML/*[local-name()="Elem"]');

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

That prints:

sn="101"

You don't need the XML either, because // denotes "anywhere in tree". So you could use:

//*[local-name()="Elem"]/@sn
/XML/*[local-name()="Elem"]/@sn

For the sake of completeness, with registering the namespace you could do it like this:

#!/usr/env/perl

use strict;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML -> load_xml ( IO => \*DATA ); 
my $xpc = XML::LibXML::XPathContext -> new;
$xpc -> registerNs('x', 'http://www.w3.org/TR/html4/');
print $xpc -> findnodes('/XML/x:Elem/@sn', $xml);

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

Now, I know this doesn't directly help with xmllint, aside from allowing testing of the xpath you're using. But I think it likely that it's quotes tripping you up, not the xpath.

Can I suggest you need:

xmllint --xpath '//*[local-name()="Elem"]/@sn' FILE_1.xml
  • 1
    Just to confirm that your xmllint --xpath '//*[local-name()="Elem"]/@sn' FILE_1.xml works perfectly (+1) – JJoao Oct 20 '16 at 18:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.