xpath buscar si existe el nodo

201

Usando una consulta xpath, ¿cómo encuentra si existe un nodo (etiqueta)?

Por ejemplo, si necesitaba asegurarme de que la página de un sitio web tenga la estructura básica correcta como / html / body y / html / head / title

EddyR
fuente
¿Quizás es mejor usar el esquema XML con indicación de elementos obligatorios? Así que verifique que un documento lo use o no.
abatishchev

Respuestas:

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

así por ejemplo

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
Patrick McDonald
fuente
41
Sorprendido con una calificación tan alta dado que la pregunta no especifica el uso de XSLT en absoluto.
tjmoore
Esto es increíble, pero ¿y si quisiera verificar si existe O está vacío?
SearchForKnowledge
3
@SearchForKnowledge, probablemente debería hacer eso como una nueva pregunta en SO, pero como una guía rápida: html/body and not(html/body/node())(es decir, simplemente pruebe si existe y no contiene ningún nodo secundario o nodo de texto).
Abel
71

Pruebe la siguiente expresión: boolean(path-to-node)

annesley
fuente
3
Esto es exactamente lo que necesitaba cuando usaba XPath en Python con lxml.
Iain Samuel McLean Élder
1
Esto funcionó de
maravilla
3
Esta es la respuesta correcta en el sentido de que en realidad es una consulta XPath, a diferencia de la mayoría de las otras respuestas.
Paul Etherton
48

Patrick tiene razón, tanto en el uso de xsl:if, como en la sintaxis para verificar la existencia de un nodo. Sin embargo, como implica la respuesta de Patrick, no hay un equivalente xsl de if-then-else, por lo que si está buscando algo más como if-then-else, normalmente es mejor usar xsl:choosey xsl:otherwise. Entonces, la sintaxis de ejemplo de Patrick funcionará, pero esta es una alternativa:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
gkrogers
fuente
+1 por señalar if-then-else, ¿y qué pasa también if-else if-else? En la respuesta de davenpcj, ¿puedo colocar test="somexpath"en el segundo cuándo hacerlo if-else if-else?
AabinGunz
3
@Abhishek Sí, puede poner más xsl: cuando tenga otras condiciones y tenga una declaración de varias sucursales. Piense en ello más como un SELECT que como un if-then-else, con xsl: de lo contrario, como predeterminado :.
davenpcj
Esto es increíble, pero ¿y si quisiera verificar si existe O está vacío?
SearchForKnowledge
13

Podría ser mejor usar una opción, no tiene que escribir (o posiblemente escribir mal) sus expresiones más de una vez, y le permite seguir comportamientos diferentes adicionales.

A menudo lo uso count(/html/body) = 0, ya que el número específico de nodos es más interesante que el conjunto. Por ejemplo ... cuando hay inesperadamente más de 1 nodo que coincide con su expresión.

<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
fuente
Como se indica en el código anterior, se pueden agregar más cláusulas xsl: when para cambiar el comportamiento y manejar múltiples condiciones de diferentes maneras.
davenpcj
count(/html/body) = 0 genio! : DI lo uso /html[count(/body)=0]/someNodepara seleccionar someNodecuándo /bodyfalta (o lo que sea)
Stefan Rogin
1
@clickstefan, /html[count(/body)=0]nunca seleccionará nada, no puede haber dos nodos raíz en XML. Quizás quisiste decir /html[count(body)=0], que sería lo mismo que /html[not(body)], o /html[not(exists(body))].
Abel
@Abel sí, / html [count (// body) = 0] o cómo dijiste, vergonzoso pero sí, no di un ejemplo adecuado
Stefan Rogin el
4

Trabajo en Ruby y usando Nokogiri busco el elemento y miro para ver si el resultado es nulo.

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
fuente
3

Una variación al usar xpath en Java usando count ():

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