Using not() in XPath

40,611

Solution 1

According to : http://msdn.microsoft.com/en-us/library/ms256086.aspx, have you tried

//*[@name != 'Bob']

Solution 2

Try

 //*[@name != 'Bob']

or

  //*[not(@name = 'Bob')]

should work both.

Solution 3

//*[@name and @name != 'Bob']
Share:
40,611

Related videos on Youtube

developer
Author by

developer

Updated on July 09, 2022

Comments

  • developer
    developer almost 2 years

    I would like how to use the "not" in XPath properly. I just can't seem to get it to work with attributes.

    Say I have this expression: //*[@name = 'Bob'] It is valid, and will return all nodes that have a name attribute equaling 'Bob'.

    Now if I want all nodes that have a name attribute that do not equal 'Bob', I need to use an XPath such as: //*[@name not(='Bob')] but this is invalid.

    I have tried multiple combinations with not() being placed in a different order, but I can't seem to get this to work. Could someone please inform me how to use not() properly?

    Also, does the order change when using elements instead of attributes? Such as: //name[text() = 'Bob']

    Thanks! :)

  • developer
    developer almost 14 years
    Doesn't this give all elements whether they have @name or not? I need it to be an element with @name and then have it not equal 'Bob'
  • Admin
    Admin almost 14 years
    @mathieu: I would be better to quote the specs (not MS documentation), from w3.org/TR/xpath/#booleans "If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true"
  • developer
    developer almost 14 years
    I think just //*[@name != 'Bob'] would work.. as others suggested. BUT This method works for numerical values but not for string values. //*[@numerical != 1] works. //*[@string != "someString"] does not. Only the root element is being returned!
  • developer
    developer almost 14 years
    This method works for numerical values but not for string values. //*[@numerical != 1] works. //*[@string != "someString"] does not. Only the root element is being returned!
  • developer
    developer almost 14 years
    @mathieu: This method works for numerical values but not for string values. //*[@numerical != 1] works. //*[@string != "someString"] does not. Only the root element is being returned!
  • Doc Brown
    Doc Brown almost 14 years
    I am pretty sure that this will work for strings. Sure you did not make an error, for example, wrong case? The comparison is case-sensitive.
  • developer
    developer almost 14 years
    @Alejandro: I did, but it only works for numerical values, not string values like I mentioned above. With the string value, the only result I get is the root node.
  • developer
    developer almost 14 years
    yes I tried various searches. I am only getting the root node returned. :S
  • Admin
    Admin almost 14 years
    @iHeartGreek: This works. Other order comparison operators (like >) only works for numbers (in XPath 2.0 you could use op:gt that works with collations).
  • Doc Brown
    Doc Brown almost 14 years
    Please post a complete example, a small XML file and the XPATH you are really trying, then we shall see further.
  • developer
    developer almost 14 years
    @Alejandro: I don't know what the problem could be then.. it doesn't work in the implementation I have. What could be possible sources of the problem?
  • Admin
    Admin almost 14 years
    @iHeartGreek: Ask other question with input sample, desired output and in progress stylesheet, and someone could answer that to you. Meanwhile, you should mark this as answer, I think.
  • developer
    developer almost 14 years
    @Alejandro: ok, I selected it as the answer. I will try to ask another question next week.
  • developer
    developer almost 14 years
    @Alejandro: I think there is an issue with my XSL code, but it only became apparent to me once I used !=. I did some further testing, and found the searches do not go through entire hierarchy. I posted a question as I still can't fix it. stackoverflow.com/questions/3451325/…
  • developer
    developer almost 14 years
    I think there is an issue with my XSL code, but it only became apparent to me once I used !=. I did some further testing, and found the searches do not go through entire hierarchy. I posted a new question as I still can't fix it. stackoverflow.com/questions/3451325/…
  • developer
    developer almost 14 years
    Sorry, it is my understanding that your solution does in fact work. I think there is an issue with my XSL code, but it only became apparent to me once I used !=. I did some further testing, and found the searches do not go through entire hierarchy. I posted a new question as I still can't fix it. stackoverflow.com/questions/3451325/…
  • outis
    outis over 10 years
    Note that //*[not(@name='Bob')] will also match elements without a name attribute: since the @name node-set will be empty, @name='Bob' will be trivially false, and not(@name='Bob') will be trivially true.
  • lvanzyl
    lvanzyl over 8 years
    Thanks for this suggestion. For some reason != wasn't working, but not() does. I was trying to hide the header row in a table with a certain class. The former returned no rows at all, the latter returned the non-header rows.