2009-04-20 25 views
182

Usando una consulta xpath, ¿cómo puede encontrar si existe un nodo (etiqueta)?xpath find if node exists

Por ejemplo si necesitaba para asegurarse de que una página web tiene la estructura básica correcta como/html/cuerpo y/html/cabeza/título

+0

Tal vez es mejor usar el esquema XML con indicación de elementos obligatorios? Por lo tanto, verifique que un documento lo use o no. – abatishchev

Respuesta

289
<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> 
+39

Sorprendido con una calificación tan alta dado que la pregunta no especifica el uso de XSLT en absoluto. – tjmoore

+0

Esto es increíble, pero ¿y si quisiera verificar si existe O está vacío? – SearchForKnowledge

+3

@SearchForKnowledge, probablemente debería preguntar eso como una nueva pregunta en SO, pero como una guía rápida: 'html/body y no (html/body/node())' (es decir, simplemente pruebe si existe y no lo hace contiene cualquier nodo hijo o nodo de texto). – Abel

2

Un variación cuando se utiliza XPath en Java usando count():

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

Esto funcionó SUPER ¡En grande! –

64

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

+3

Esto es exactamente lo que necesitaba cuando uso XPath en Python con lxml. –

+1

Esto funcionó muy bien al construir Condiciones de reglas y Acciones de reglas dentro de InfoPath 2010. – Merenzo

+3

Esta es la respuesta correcta en el sentido de que se trata de una consulta XPath, a diferencia de la mayoría de las otras respuestas. –

11

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.

Uso muy a menudo count(/html/body) = 0, ya que el número específico de nodos es más interesante que el conjunto. Por ejemplo ... cuando inesperadamente hay más de 1 nodo que coincida 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> 
+0

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

+0

'count (/ html/body) = 0' genius! : D Lo uso como '/ html [count (/ body) = 0]/someNode' para seleccionar' someNode' cuando '/ body' (o lo que sea) falta –

+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

38

Patrick es correcta, tanto en el uso de la xsl:if, y en la sintaxis para la comprobación de la existencia de un nodo. Sin embargo, como implica la respuesta de Patrick, no hay equivalente xsl a if-then-else, por lo que si buscas algo más parecido a un if-then-else, normalmente es mejor usar xsl:choose y xsl:otherwise. Por lo tanto, un ejemplo de sintaxis de Patrick va a funcionar, pero esto es una alternativa:

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

+1 para anotar 'if-then-else', también sobre' if-else if-else'? En la respuesta de davenpcj ¿puedo colocar 'test =" somexpath "' en el 2do cuando para hacerlo 'if-else if-else'? – abi1964

+3

@Abhishek Sí, puedes poner más xsl: cuando con otras condiciones y tener una instrucción de múltiples sucursales. Piense en ello más como un SELECCIONE que como un if-then-else, con xsl: de lo contrario, como valor predeterminado :. – davenpcj

+0

Esto es increíble, pero ¿y si quisiera verificar si existe O está vacío? – SearchForKnowledge

3

trabajo en Rubí y el uso de Nokogiri voy a buscar el elemento y mira a 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? 
Cuestiones relacionadas