xpath trouver si le nœud existe

201

À l'aide d'une requête xpath, comment savoir s'il existe un nœud (balise)?

Par exemple, si je devais m'assurer qu'une page de site Web a la structure de base correcte comme / html / body et / html / head / title

EddyR
la source
Peut-être vaut-il mieux utiliser XML Schema avec indication obligatoire des éléments? Vérifiez donc qu'un document l'utilise ou non.
abatishchev

Réponses:

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

donc par exemple

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
Patrick McDonald
la source
41
Surpris à une note aussi élevée étant donné que la question ne spécifie pas du tout l'utilisation de XSLT.
tjmoore
C'est génial mais si je voulais vérifier s'il existe OU vide?
SearchForKnowledge
3
@SearchForKnowledge, vous devriez probablement poser cette question comme une nouvelle question à SO, mais comme un guide rapide: html/body and not(html/body/node())(c'est-à-dire, testez simplement si elle existe et qu'elle ne contient aucun nœud enfant ou nœud texte).
Abel
71

Essayez l'expression suivante: boolean(path-to-node)

annesley
la source
3
C'est exactement ce dont j'avais besoin lors de l'utilisation de XPath en Python avec lxml.
Iain Samuel McLean Elder
1
Cela a fonctionné lors de la construction des conditions de règle et des actions de règle dans InfoPath 2010.
Merenzo
3
Il s'agit de la bonne réponse dans le sens où il s'agit en fait d'une requête XPath, contrairement à la plupart des autres réponses.
Paul Etherton
48

Patrick a raison, à la fois dans l'utilisation de xsl:ifet dans la syntaxe pour vérifier l'existence d'un nœud. Cependant, comme l'indique la réponse de Patrick, il n'y a pas de xsl équivalent à if-then-else, donc si vous cherchez quelque chose de plus comme un if-then-else, il vaut mieux utiliser xsl:chooseet et xsl:otherwise. Ainsi, l'exemple de syntaxe de Patrick fonctionnera, mais ceci est une alternative:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
gkrogers
la source
+1 pour noter if-then-else, qu'en est-il également if-else if-else? Dans la réponse de davenpcj, puis-je placer test="somexpath"dans le 2e quand le faire if-else if-else?
AabinGunz
3
@Abhishek Oui, vous pouvez mettre plus de xsl: quand avec d'autres conditions et avoir une instruction multi-branches. Considérez-le plus comme un SELECT qu'un if-then-else, avec xsl: autrement comme valeur par défaut:.
davenpcj
C'est génial mais si je voulais vérifier s'il existe OU vide?
SearchForKnowledge
13

Il pourrait être préférable d'utiliser un choix, de ne pas avoir à taper (ou peut-être de mal saisir) vos expressions plus d'une fois et vous permet de suivre des comportements différents supplémentaires.

J'utilise très souvent count(/html/body) = 0, car le nombre spécifique de nœuds est plus intéressant que l'ensemble. Par exemple ... quand il y a de manière inattendue plus d'un nœud qui correspond à votre expression.

<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
la source
Comme indiqué dans le code ci-dessus, davantage de clauses xsl: when peuvent être ajoutées pour modifier le comportement et gérer plusieurs conditions de différentes manières.
davenpcj
count(/html/body) = 0 génie! : DI l'utilise comme /html[count(/body)=0]/someNodepour sélectionner someNodequand /body(ou autre) est manquant
Stefan Rogin
1
@clickstefan, /html[count(/body)=0]ne sélectionnera jamais rien, il ne peut pas y avoir deux nœuds racine en XML. Peut-être que vous vouliez dire /html[count(body)=0], ce qui serait le même que /html[not(body)], ou /html[not(exists(body))].
Abel
@Abel oui, / html [count (// body) = 0] ou comment vous l'avez dit, honteux mais oui je n'ai pas donné un bon exemple
Stefan Rogin
4

Je travaille en Ruby et en utilisant Nokogiri, je récupère l'élément et regarde si le résultat est nul.

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
la source
3

Une variation lors de l'utilisation de xpath en Java en utilisant count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
user324898
la source