Выбор XPath при исключении элементов, имеющих определенные значения атрибута - PullRequest
7 голосов
/ 10 сентября 2010

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

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

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

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

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

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

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

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

Что мне здесь не хватает?

Приветствия,
Исаак

Ответы [ 4 ]

3 голосов
/ 10 сентября 2010

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

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

Ожидаете ли вы, что узел p, окружающий ваш span, не будет выбран?

1 голос
/ 20 августа 2013

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

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

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

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

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

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

0 голосов
/ 10 сентября 2010

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

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

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

это должно выбрать все дочерние элементы (*) элемента div, которые не имеют дочернего элемента с атрибутом class, равным bad.

Изменить:

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

/root/div/*[not(*/@class "bad")]
0 голосов
/ 10 сентября 2010

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...