xpath encontra se o nó existe

201

Usando uma consulta xpath, como você descobre se existe um nó (tag)?

Por exemplo, se eu precisasse garantir que uma página de site tivesse a estrutura básica correta, como / html / body e / html / head / title

EddyR
fonte
Talvez seja melhor usar o XML Schema com indicação de elementos obrigatórios? Portanto, verifique se um documento o usa ou não.
abatishchev

Respostas:

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

então por exemplo

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
Patrick McDonald
fonte
41
Surpreso com uma classificação tão alta, pois a pergunta não especifica o uso do XSLT.
tjmoore
Isso é incrível, mas e se eu quisesse verificar se existe OU está vazio?
SearchForKnowledge
3
@SearchForKnowledge, você provavelmente deve fazer isso como uma nova pergunta na SO, mas como um guia rápido: html/body and not(html/body/node())(ou seja, apenas teste se existe e se não contém nós filhos ou nós de texto).
Abel
71

Tente a seguinte expressão: boolean(path-to-node)

Annesley
fonte
3
Isso é exatamente o que eu precisava ao usar o XPath em Python com lxml.
Iain Samuel McLean Elder
1
Isso funcionou um deleite ao construir condições de regras e ações de Regras dentro InfoPath 2010.
Merenzo
3
Esta é a resposta correta no sentido de que na verdade é uma consulta XPath, diferente da maioria das outras respostas.
Paul Etherton
48

Patrick está correto, tanto no uso de xsl:ifquanto na sintaxe para verificar a existência de um nó. No entanto, como a resposta de Patrick implica, não há xsl equivalente a if-then-else, portanto, se você está procurando algo mais como um if-then-else, normalmente é melhor usar xsl:choosee xsl:otherwise. Portanto, a sintaxe de exemplo de Patrick funcionará, mas esta é uma alternativa:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
gkrogers
fonte
+1 para notar if-then-else, e também if-else if-else? Na resposta de davenpcj posso colocar test="somexpath"no 2º quando fazê-lo if-else if-else?
AabinGunz
3
@Abhishek Sim, você pode colocar mais xsl: quando com outras condições e ter uma declaração de várias ramificações. Pense nisso mais como um SELECT do que um if-then-else, com xsl: else como o padrão :.
Davidpcj
Isso é incrível, mas e se eu quisesse verificar se existe OU está vazio?
SearchForKnowledge
13

Pode ser melhor usar uma opção, não precisar digitar (ou possivelmente digitar incorretamente) suas expressões mais de uma vez e permitir que você siga comportamentos diferentes adicionais.

Eu costumo usar count(/html/body) = 0, pois o número específico de nós é mais interessante que o conjunto. Por exemplo ... quando houver inesperadamente mais de um nó que corresponda à sua expressão.

<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
fonte
Conforme indicado no código acima, mais cláusulas xsl: when podem ser adicionadas para alterar o comportamento e manipular várias condições de maneiras diferentes.
Davidpcj
count(/html/body) = 0 gênio! : DI usá-lo como /html[count(/body)=0]/someNodepara selecionar someNodequando /body(ou qualquer outro) está faltando
Stefan Rogin
1
@clickstefan, /html[count(/body)=0]nunca selecionará nada, não pode haver dois nós raiz no XML. Talvez você quis dizer /html[count(body)=0], o que seria o mesmo que /html[not(body)], ou /html[not(exists(body))].
Abel
@Abel sim, / html [count (// corpo) = 0] ou como você disse, vergonhoso, mas sim, eu não dar um bom exemplo
Stefan Rogin
4

Eu trabalho em Ruby e usando Nokogiri eu pego o elemento e procuro ver se o resultado é 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
fonte
3

Uma variação ao usar xpath em Java usando count ():

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