Testing for an XML attribute

hendry picture hendry · Apr 7, 2011 · Viewed 28.9k times · Source

I have a piece of XML like so:

<root>
    <foo src=""/>
    <foo src="bar"/>
    <foo />
</root>

I want to know which elements have a src attribute, which are empty and which have values.

The furthest I have come is with

$ xmlstarlet sel -t -m '//foo' -v @src -n foo.xml 

bar

Though that doesn't tell me the third foo is missing the attribute.

Answer

Jean-Fran&#231;ois Corbett picture Jean-François Corbett · Apr 7, 2011

This will select the foos with no src attribute.

/root/foo[not(@src)]

For the other two tasks, I would use a mix of the expressions pointed out by @TOUDIdel and @Dimitre Novatchev: /root/foo[@src and string-length(@src)=0] for foos with an empty src, and /root/foo[@src and string-length(@src)!=0] for foos with an src with content in it.

As an aside, I would avoid using the "anywhere" selector, // (not to mention the * wildcard), unless you're sure that this is specifically what you need. // is like making your very eager dog sniff a piece of cloth and telling it, "bring me everything that smells like this, wherever you find it". You won't believe the weird crap it can decide to bring back.