Métoule
Métoule

Reputation: 14502

XPath expression to select a node if attribute matches, or a node without this attribute otherwise

Considering the following XML

<xml>
  <tag/>
  <tag version="2.1"/>
</xml>

I want an XPath 1.0 expression that returns <tag version="2.1"/> if I search for version 2.1, and <tag/> if I search for version 2.2.

So far, I've tried

/xml/tag[@version = '%version%' or not(@version)]

where %version% is a string that can be either 2.1 or 2.2, but if %version% is 2.1, it returns both nodes.

Upvotes: 0

Views: 344

Answers (2)

Jirka Š.
Jirka Š.

Reputation: 3428

As xpath 2.0 (if relevant) alternative to very nice @paul answer you could use

if (/xml/tag[@version = '2.1']) then /xml/tag[@version = '2.1'] else /xml/tag[not(@version)] 

resp.

if (/xml/tag[@version = '%version%']) then /xml/tag[@version = '%version'] else /xml/tag[not(@version)] 

Upvotes: 3

paul trmbrth
paul trmbrth

Reputation: 20748

You can use something like this, using | (or)

    /xml[not(tag[@version="2.1"])]/tag[not(@version)] |
    /xml[tag[@version="2.1"]]/tag[@version="2.1"]
  • either xml doesn't have tags with version="2.1", then return tags with no version attribute
  • or, if xml does contain tags with version="2.1", return these

So that would be in your case

    /xml[not(tag[@version='%version%'])]
        /tag[not(@version)]
    |
    /xml[tag[@version='%version%']]
        /tag[@version='%version%']

Upvotes: 3

Related Questions