Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XPath - invert selection

Tags:

xslt

xpath

I'm writing an xpath and I wrote the xpath which matches some nodes in the document tree

But I'd like to match all the other elements instead, so I'd like to inverse the selection in the context of the whole document

So let's say we have the following xpath

//*[@id='menu']//*

and document

<body>
<div>
  <h1>title</h1>
</div>
<div>
<div id="menu">
  <UL>
    <LI>home</LI>
    <LI>about</LI>
  </UL>
</div>
<div id="sidebar">
  <ul>
    <li>one</li>
    <li>two</li>
  </ul>
</div>
<div>
</body>

so the uppercased nodes are matched, but what I want to achieve is mark all the lowercase nodes.

Thanks for your help

like image 265
Jan Vorcak Avatar asked Jun 24 '26 00:06

Jan Vorcak


1 Answers

Your original XPath expression

//*[@id='menu']//*

matches all element nodes that are descendants of the <div id="menu"> (but not the div element itself). Depending on exactly what you mean by the "inverse" you could try something like

//*[not(ancestor::*[@id='menu'])]

which matches all element nodes that do not have an ancestor with id="menu", which would include the div with id="menu" but not its children or grandchildren. If you want to exclude the div as well, use ancestor-or-self:: instead of ancestor::


If you have XPath 2.0 then a more general answer to your original question is to look at the except operator - in XPath 2.0 you can say X except Y to select all the nodes matched by expression X but not also by Y

//* except //*[@id='menu']//*

There are also union (nodes matched by either X or Y) and intersect (both X and Y) operators.

like image 59
Ian Roberts Avatar answered Jun 25 '26 19:06

Ian Roberts