Search code examples
xmlxpathxmllint

How to get all attributes with same tag name with xmllint xpath


Sample xml-

<xml>
<Tag name="attr1"></Tag>
<Tag name="attr2"></Tag>
<Tag name="attr2"></Tag>
</xml>

How can I get values of all the attributes with xmllint, like this-

attr1
attr2
attr3

I can only use xmllint. I have tried this-

xmllint --xpath 'string(//Tag/@name)'

But this only returns first match.


Solution

  • Using string() will only give you the first match in XPath 1.0. If you remove string() you'll get all three attributes, but you'd have to post-process them to get only the values. I suppose this will depend on how you're running xmllint (what os/shell/etc).

    Something like (tested with bash in cygwin)...

    attrs=$(xmllint --xpath "//Tag/@name" sample.xml)
    echo $attrs | sed 's/\s*name="\([^"]*\)"/\1\n/g'
    

    Another option is to first get a count of how many Tag elements and then call xmllint that many times with a positional predicate on Tag.

    Something like (tested with bash in cygwin)...

    count=$(xmllint --xpath "count(//Tag)" sample.xml)
    
    if [[ $count != 0 ]]; then
        for ((i=1; i<=$count; i++)); do
           echo $(xmllint --xpath "string(//Tag[$i]/@name)" sample.xml)
        done
    fi