xpathxpath-2.0

Using XPath to select a descendant node that doesn't have a specified intermediate node


Using XPath 2.0 (ideally) or 3.0 (an option), I'd like to select a node C that is a descendant of A as long as the path from A to C does not contain any B nodes.

<Root>
  <Other>
    <A>
      <Other>
        <C/> <!--selected-->
      </Other>
      <Other>
        <B>
          <Other>
            <C/> <!--not selected-->
          </Other>
        </B>
      </Other>
    </A>
  </Other>
</Root>

Other represents 0 or more nested non-B nodes.

A may have B ancestors.


Solution

  • I would write

    //A/(.//C except .//B//C)
    

    except perhaps if it's a very large document and performance is a concern, in which case I might implement my own transitive closure over (child::* except child::B).