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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With