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 thing
s 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.
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