Question

I have an XML file I need to parse from the shell. It looks somewhat like this:

<?xml version="1.0" encoding="UTF-8"?>
<things>
    <thing>
        <foo>123</foo>
        <bar>false</bar>
    </thing>
    <thing>
        <bar>true</bar>
        <foo>abc</foo>
    </thing>
</things>

Note that the order of the child nodes of things is arbitrary. In my real-world data, there are a couple of other child nodes inside each thing.

Now, the value of foo is unique. I need to get the value of the child node bar for the thing whose child foo's value is, say, abc. I've tried to use an XPath query with xmllint but no luck. I can't get a match; or, if I just test with a more general query, I get the entire tree.

$ xmllint --pattern //thing[foo='abc']/bar test.xml
xmllint: No match.
$ xmllint --pattern //thing/bar test.xml
(the whole tree)

I was hoping just to get true.

What am I doing wrong? I don't have access to the --xpath flag other questions mention, so if that's the answer then I'm out of luck.

Was it helpful?

Solution

Try this command:

xmllint --xpath '//thing[foo="abc"]/bar/text()' test.xml

Another command:

echo 'cat //thing[foo="abc"]/bar/text()' | xmllint --shell test.xml

Also try xmlstarlet:

xmlstarlet sel -t -m '//thing[foo="abc"]/bar' -v 'text()' test.xml
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top