Xpath для исключения элементов, имеющих класс

Я пытаюсь выбрать все элементы dom, которые имеют id="mydiv", но исключают те, у которых также есть class="exclass". Сейчас я делаю первую часть //*[@id="mydiv"]. Как добавить часть исключения класса?

P.S. Если вам интересно, почему мне нужно выбрать несколько элементов с одинаковым идентификатором, я просто работаю над существующим DOM, который я не могу контролировать.

Ответ 1

Вы можете использовать отрицание:

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

Если атрибут class может не существовать на всех узлах, вам понадобится следующее:

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

Последняя (несколько) нечетная логика может быть превращена в то, что предложил Майкл:

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

Хотя, лично тот факт, что XPath не может делать сравнения, если атрибут отсутствует, немного напоминает недостаток.

Ответ 2

Ответ на поставленный вопрос:

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

Первая половина условия истинна, если есть атрибут @id, а его значение - mydiv. Вторая половина имеет значение true, если нет атрибута @class со значением exclass: то есть, если атрибут класса отсутствует, или есть атрибут класса, а его значение является чем-то иным, чем "exclass".

Избегайте использования! = В этой ситуации: 90% времени, если вы думаете о написании A!=B, вы, вероятно, not(A=B) хотели not(A=B). Значение отличается в том случае, когда либо A, либо B не является одиночным, то есть там, где он либо пуст, либо может содержать несколько значений.