Testing for an XML attribute

2019-03-17 14:04发布

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.

4条回答
够拽才男人
2楼-- · 2019-03-17 14:26

/root/foo[string-length(@src)!=0] return all foo elements have non empty value.

Unfortunately /root/foo[string-length(@src)=0] indicates elements which don't have src attribute and also elements have src attribute but empty.

查看更多
看我几分像从前
3楼-- · 2019-03-17 14:35

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.

查看更多
戒情不戒烟
4楼-- · 2019-03-17 14:48

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

Elements having a @src attribute which is empty (no string-value):

//*[@src[not(string())]]

Elements having a @src attribute which has value (string-value):

//*[string(@src)]

From http://www.w3.org/TR/xpath/#section-String-Functions

A node-set is converted to a string by returning the string-value of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned.

From http://www.w3.org/TR/xpath/#function-boolean

A string is true if and only if its length is non-zero.

查看更多
等我变得足够好
5楼-- · 2019-03-17 14:51

Use:

//*[@src and not(string-length(@src))]

This selects all elements in the XML document that have a src attribute whose string-value has length of zero.

//*[@src and string-length(@src)]

This selects all elements in the XML document that have a src attribute whose string-value has length that is not zero.

//*[@src and string-length(normalize-space(@src))]

This selects all elements in the XML document that have a src attribute whose string-value after excluding the starting and ending whitespace has length that is not zero.

//[not(@src)]

This selects all elements in the XML document that don't have a src attribute.

查看更多
登录 后发表回答