Xmllint display values of more than 1 attributes in single execution

command linedataxmlxmllint

I am using xmllint to parse xml file which has several tags and each tag has several attributes. Sample structure as shown below:

<root>
   <child attr1="abc" attr2="def" attr3="ghi" />
   ...
   ...
</root>

I need to fetch the values from the attributes attr1,attr2 and attr3.

So far, I have tried the following which is giving the data of one attribute perfectly

echo 'cat //root/child/@attr1' | xmllint --shell data.xml 

This output

attr1="abc"

So, my question is, how can we specify more than one attributes in the string to get the required output as

attr1="abc"
attr2="def"
attr3="ghi"

I tried the following for this, but no good result:

echo 'cat //root/child/@*[attr1|attr2|attr3]' | xmllint --shell data.xml 
echo 'cat //root/child/@*[attr1 or attr2 or attr3]' | xmllint --shell data.xml 

output for above was that the echo statement was re-echoed again that means, the xmllint didn't accept it as input.

Any ideas on how to go about this?

Best Answer

As far as I know the | separator can be used only on entire paths:

echo 'cat /root/child/@attr1|/root/child/@attr2|/root/child/@attr3' | xmllint --shell data.xml

(As // means at any depth, “//root” puts the parser to pointless extra work. Assuming your sample XML looks has similar structure as the real one (so root is indeed the XML's root node), better use “/root/child”.)

Or you can use an expression with XPath functions:

echo 'cat /root/child/@*[name()="attr1" or name()="attr2" or name()="attr3"]' | xmllint --shell data.xml

If you need all attributes with “attr*” name, you can use a generic expression:

echo 'cat /root/child/@*[starts-with(name(),"attr")]' | xmllint --shell data.xml
Related Question