xpath найти, если узел существует


201

Используя запрос xpath, как определить, существует ли вообще какой-либо узел (тег)?

Например, если мне нужно убедиться, что страница сайта имеет правильную базовую структуру, такую ​​как / html / body и / html / head / title


Может быть, лучше использовать XML-схему с обязательным указанием элементов? Поэтому убедитесь, что документ использует это или нет.
Абатищев

Ответы:


321
<xsl:if test="xpath-expression">...</xsl:if>

так например

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>

41
Удивлен такой высокой оценкой, учитывая, что вопрос вообще не определяет использование XSLT.
tjmoore

Это круто, но что если я хотел проверить, существует ли он ИЛИ пуст?
SearchForKnowledge

3
@SearchForKnowledge, вам, вероятно, следует задать этот вопрос в качестве нового вопроса в SO, но в качестве краткого руководства: html/body and not(html/body/node())(т.е. просто проверьте, существует ли он и не содержит ли он дочерних узлов или текстовых узлов).
Авель

71

Попробуйте следующее выражение: boolean(path-to-node)


3
Это именно то, что мне было нужно при использовании XPath в Python с lxml.
Иэн Сэмюэль Маклин, старейшина

1
Это сработало, когда создавались Условия Правил и Действия Правил в InfoPath 2010.
Merenzo

3
Это правильный ответ в том смысле, что на самом деле это запрос XPath, в отличие от большинства других ответов.
Пол Этертон

48

Патрик прав как в использовании xsl:ifсинтаксиса, так и в синтаксисе для проверки существования узла. Однако, как показывает ответ Патрика, xsl-эквивалента if-then-else нет, поэтому, если вы ищете что-то более похожее на if-then-else, вам, как правило, лучше использовать xsl:chooseи xsl:otherwise. Итак, пример синтаксиса Патрика будет работать, но это альтернатива:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>

+1 к сведению if-then-else, а как насчет if-else if-else? В ответе davenpcj я могу поставить test="somexpath"во 2-й, когда это сделать if-else if-else?
AabinGunz

3
@Abhishek Да, вы можете поставить больше xsl: когда с другими условиями и иметь многоотраслевой оператор. Думайте об этом больше как о SELECT, а не как о чем-то еще, с xsl: иначе как значением по умолчанию :.
davenpcj

Это круто, но что если я хотел проверить, существует ли он ИЛИ пуст?
SearchForKnowledge

13

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

Я очень часто пользуюсь count(/html/body) = 0 , так как конкретное количество узлов интереснее, чем множество. Например ... когда неожиданно найдется более одного узла, соответствующего вашему выражению.

<xsl:choose>
    <xsl:when test="/html/body">
         <!-- Found the node(s) -->
    </xsl:when>
    <!-- more xsl:when here, if needed -->
    <xsl:otherwise>
         <!-- No node exists -->
    </xsl:otherwise>
</xsl:choose>

Как указано в приведенном выше коде, можно добавить дополнительные предложения xsl: when, чтобы изменить поведение и обрабатывать несколько условий различными способами.
davenpcj

count(/html/body) = 0 гений! : D Я использую его как /html[count(/body)=0]/someNodeдля выбора, someNodeкогда /body(или что-то еще) отсутствует
Стефан Рогин

1
@clickstefan, /html[count(/body)=0]никогда ничего не выберет, в XML не может быть двух корневых узлов. Может быть, вы имели в виду /html[count(body)=0], что будет так же, как /html[not(body)]или /html[not(exists(body))].
Авель

@Abel да, / html [count (// body) = 0] или как ты сказал, позорно, но да, я не привел подходящего примера
Стефан Рогин,

4

Я работаю в Ruby и с помощью Nokogiri извлекаю элемент и проверяю, равен ли результат нулю.

require 'nokogiri'

url = "http://somthing.com/resource"

resp = Nokogiri::XML(open(url))

first_name = resp.xpath("/movies/actors/actor[1]/first-name")

puts "first-name not found" if first_name.nil?

3

Вариант при использовании xpath в Java с использованием count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.