Search code examples
xmlbashxpathubuntu-18.04xmlstarlet

Getting attribute value from XML in bash script with XPath string()


Preamble:
This is not a duplicate since all other topics do not answer my specific issue.
I'm on Xubuntu 18.04
using libxml-xpath-perl 1.42 (if that matters)

Problem:
I have an XML, let's say like so:

<root>
    <level1>
        <somechild foo="bar" />
    </level1>
</root

I want to get the value bar from somechilds attribute foo. However, when I query

FOO=$(xpath -e '/root/level1/somechild/@foo' $XMLFILE)"

in my bash script it returns foo="bar" instead of bar.

I've already researched this issue and found out that I have to do something with string() but I just cannot figure out what the right syntax is for that.

I've tried the string() function in various places but the closest I got to success, so far was

FOO="$(xpath -e 'string(/root/level1/somechild/@foo)' $XMLFILE)"

In this case echo $FOO gives me

Query didn't return a nodeset. Value: bar

Still not what I want but at least no error and the Value is recognized as bar

How do I use this properly?


Solution

  • With valid XML:

    xpath -e 'string(//root/level1/somechild/@foo)' file.xml 2>/dev/null 
    

    or

    xmlstarlet select --text --template --copy-of 'string(//root/level1/somechild/@foo)' file.xml
    

    or

    xmlstarlet select --text --template --match '//root/level1/somechild' --value-of '@foo' file.xml
    

    Output:

    bar