Выбор XPath при исключении элементов, имеющих определенные значения атрибутов

мой первый пост здесь-это отличный сайт, и я, безусловно, сделаю все возможное, чтобы вернуть как можно больше.

Я видел различные проявления этого следующего вопроса; однако мои попытки решить, похоже, не работают.

рассмотрим это простое дерево:

<root>
    <div>
        <p>hello</p>
        <p>hello2</p>
        <p><span class="bad">hello3</span></p>
    </div>
</root>

Я хотел бы придумать выражение XPath, которое будет выбирать все дочерние узлы "div",за исключением для элементов, у которых атрибут "class" равен "плохой."

вот что я пробовал:

/root/div/node()[not (@class='bad')]

... Однако это, похоже, не работает.

что я пропустила?

спасибо,
Исаак!--3-->

4 ответов


при тестировании XPath здесь С предоставленным XML-документом XPath, похоже, действительно выбирает все дочерние узлы, у которых нет атрибута class="bad" - Это все <p> элементы в документе.

вы заметите, что единственным дочерним узлом, имеющим такой атрибут, является <span>, который действительно не выбран.

вы ожидаете p узел вокруг вашего span не быть выбранным?


я работал с XPath в Java-программе, которую я пишу. Если вы хотите выбрать узлы, у которых нет class= " bad "(т. е. <span> узлы, но не на окружающие <p> nodes), вы можете использовать:

/root/div/descendant::*[not (@class='bad')]

в противном случае, если вы хотите выбрать

узлы, у которых нет ребенка с class= 'bad', вы можете использовать что-то вроде следующего:

/root/div/p/*[not (@class='bad')]/..

на .. часть выбирает родительский узел.


преобразование идентичности просто соответствует и копирует все:

<xsl:template match="@*|node()" >
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

но вы добавляете нулевое преобразование, которое точнее соответствует шаблону, который вы хотите исключить:

 <xsl:template match="span[@class='bad']" />

( вы также можете добавить приоритет attrib, если вы хотите быть более явным о том, какой из них имеет приоритет. )


Добро пожаловать в SO, Исаак!

Я бы попробовал это:

/root/div/*[./*[@class != "bad"]]

это должно выбрать все дочерние элементы (*) из div элемент, который не является потомком элемента , что составляет bad.

Edit:

согласно комментарию @Alejandros:

/root/div/*[not(*/@class "bad")]