1

Hi I know this is quite basic but I wasn't able to find the answer by myself.

In this example:

<root>
   <a/>
   <b/>
   <c/>
   <d/>
</root>

I want to select all root children except b and d.

I wrote something like this that didn't work.

/root/*[not(b) and not(d)]

the result is all the root children: a,b,c,d. How to select only a and c?

har07
  • 88,338
  • 12
  • 84
  • 137
Hairi
  • 3,318
  • 2
  • 29
  • 68

3 Answers3

2

"I want to select all root children except b and d"

Your attempted XPath missed self axis :

/root/*[not(self::b) and not(self::d)]
har07
  • 88,338
  • 12
  • 84
  • 137
1

The correct xpath is /root/*[name() != 'b' and name() != 'c'], i checked the name of the node

bdn02
  • 1,500
  • 9
  • 15
1

If you're using XPath 2.0, you can use the following, which maybe is a bit shorter and easier to read if you have to update your list of exclusions:

/root/*[not(name() = ('b', 'c'))]

This takes advantage of XPath 2.0's = operator on sequences, which returns true if there is one equal pair of items in the compared sequences. So if an element's name() is either 'b' or 'c', the comparison is true, and then you want to exclude the node (hence the not()).

Also, check What is the difference between name() and local-name()? to see if you should use name() or local-name(). In most cases, what people actually want is local-name().

Community
  • 1
  • 1
dret
  • 531
  • 3
  • 7