XPath find if node exists
Asked Answered
L

6

209

Using a XPath query how do you find if a node (tag) exists at all?

For example if I needed to make sure a website page has the correct basic structure like /html/body and /html/head/title.

Libre answered 20/4, 2009 at 11:14 Comment(1)
Maybe it's better to use XML Schema with obligatory elements indication? So check that a document uses it or not.Cockneyism
F
333
<xsl:if test="xpath-expression">...</xsl:if>

so for example

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>
Furnishings answered 20/4, 2009 at 11:26 Comment(1)
@SearchForKnowledge, you should probably ask that as a new question at SO, but as a quick guide: html/body and not(html/body/node()) (i.e., just test if it exists and it does not contain any child nodes, or text nodes).Betook
B
76

Try the following expression: boolean(path-to-node)

Bedrock answered 20/9, 2010 at 12:37 Comment(3)
This is exactly what I needed when using XPath in Python with lxml.Franklin
This worked a treat when constructing Rule Conditions and Rule Actions within InfoPath 2010.Mucilage
This is the correct answer in the sense that this is actually an XPath query, unlike most of the other answers.Festivity
R
51

Patrick is correct, both in the use of the xsl:if, and in the syntax for checking for the existence of a node. However, as Patrick's response implies, there is no xsl equivalent to if-then-else, so if you are looking for something more like an if-then-else, you're normally better off using xsl:choose and xsl:otherwise. So, Patrick's example syntax will work, but this is an alternative:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>
Rapture answered 4/7, 2011 at 10:38 Comment(3)
+1 for noting if-then-else, also what about if-else if-else? In davenpcj's answer can I place test="somexpath" in the 2nd when to make it if-else if-else?Guthrie
@Abhishek Yes, you can put more xsl:when with other conditions and have a multi-branch statement. Think of it more like a SELECT than an if-then-else, with xsl:otherwise as the default:.Striker
This is awesome but what if I wanted to check if it exists OR empty?Billbillabong
S
14

Might be better to use a choice, don't have to type (or possibly mistype) your expressions more than once, and allows you to follow additional different behaviors.

I very often use count(/html/body) = 0, as the specific number of nodes is more interesting than the set. For example... when there is unexpectedly more than 1 node that matches your 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>
Striker answered 1/5, 2011 at 17:3 Comment(4)
As indicated in the code above, more xsl:when clauses can be added to change the behavior and handle multiple conditions in different ways.Striker
count(/html/body) = 0 genius ! :D I use it as /html[count(/body)=0]/someNode for selecting someNode when /body (or whatever) is missingStakeout
@clickstefan, /html[count(/body)=0] will never select anything, there cannot be two root nodes in XML. Maybe you meant /html[count(body)=0], which would be the same as /html[not(body)], or /html[not(exists(body))].Betook
@Betook yes, /html[count(//body)=0] or how you said, shameful but yes I didn't give a proper exampleStakeout
B
4

I work in Ruby and using Nokogiri I fetch the element and look to see if the result is nil.

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?
Barbabas answered 16/2, 2012 at 23:30 Comment(0)
R
3

A variation when using xpath in Java using count():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
Renatarenate answered 25/4, 2010 at 12:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.