How to filter with XPath on all elements without a specific attribute

32,285

Solution 1

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.

Solution 2

You are very close:

//StateProvince[not(@territory) or @territory != 'true']

Should get you the result you want.

Solution 3

This should work:

//StateProvince[not(@territory='true')]
Share:
32,285
lyngbym
Author by

lyngbym

Updated on July 09, 2022

Comments

  • lyngbym
    lyngbym almost 2 years

    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.

  • lyngbym
    lyngbym about 15 years
    I agree this is also good practice, but in my case it is just a very small xml that will be cached after it is loaded.
  • Dimitre Novatchev
    Dimitre Novatchev about 15 years
    @lyngbym Even for small XML documents using '//' may terribly affect performance (if these XPath expressions are issued frequently). Also, if one gets used to '//' with small docs, then the chances are great (s)he will forget and use it with bigger documents and thus create a performance disaster. After all, who decides how small is "small" and where it stops to be "small" ?