How to filter with XPath on all elements without a specific attribute
Question
My XPath is a little bit rusty... Let's say I have this simple XML file:
<?xml version="1.0" encoding="utf-8" ?>
<States xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<States>
<StateProvince name="ALABAMA" abbrev="AL" />
....
<StateProvince name="AMERICAN SAMOA" abbrev="AS" territory="true" />
</States>
</States>
I would like to run a simple XPath query to parse out all of the true states (so don't pull in states where territory = true). I tried \StateProvince[@territory!='true'] but I got zero. Other variations seem to be failing. This seems like it should be simple, but not finding what I want.
Any help appreciated.
Solution
One XPath expression that selects the wanted elements:
/*/States/StateProvince[not(@territory='true')]
Do note that one must avoid the //
abbreviation whenever possible as it causes the whole document (subtree rooted at the context node) to be scanned.
The above XPath expression avoids the use of the //
abbreviation by taking into account the structure of the originally-provided XML document.
Only if the structure of the XML document is completely unknown (and the XPath expression is intended to be used accross many XML documents with unknown structure) should the use of the //
abbreviation be considered.
OTHER TIPS
You are very close:
//StateProvince[not(@territory) or @territory != 'true']
Should get you the result you want.
This should work:
//StateProvince[not(@territory='true')]