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)

    1 Answer 1

    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 
    0

      You must log in to answer this question.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.