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

201

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

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

EddyR
источник
Может быть, лучше использовать 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>
gkrogers
источник
+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>
davenpcj
источник
Как указано в приведенном выше коде, можно добавить дополнительные предложения 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?
bcolfer
источник
3

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

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
user324898
источник