Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xpath to exclude elements that have a class

I'm trying to select all dom elements that have id="mydiv" but exclude the ones that also have the class="exclass". Right now I'm doing the first part //*[@id="mydiv"]. How do I add the class exclusion part?

P.S. In case you're wondering why I need to select multiple elements that have the same id, I'm just working on an existing DOM that I can't control.

like image 942
sameold Avatar asked Jun 20 '12 05:06

sameold


2 Answers

You can use negation:

//*[@id="mydiv" and @class!="exclass"]

If the class attribute may not exist on all nodes, you need this:

//*[@id="mydiv" and (not(@class) or @class!="exclass")]

The last (somewhat) odd logic can be turned into what Michael proposed:

//*[@id="mydiv" and not(@class="exclass")]

Though, personally, the fact that XPath cannot make comparisons if the attribute is missing feels a bit like a shortcoming.

like image 102
Ja͢ck Avatar answered Nov 20 '22 00:11

Ja͢ck


The answer to the question as written is

//*[@id="mydiv" and not(@class="exclass")]

The first half of the condition is true if there is an @id attribute and its value is mydiv. The second half is true if there is no @class attribute with the value exclass: that is, if there is no class attribute, or if there is a class attribute and its value is something other than "exclass".

Avoid using != in this situation: 90% of the time, if you think of writing A!=B, you probably wanted not(A=B). The meaning is different in the case where either A or B is not a singleton, that is, where it is either empty, or can contain multiple values.

like image 9
Michael Kay Avatar answered Nov 20 '22 01:11

Michael Kay