7
votes

I have a set of data called <testData> with many nodes inside.

How do I detect if the node exists or not?

I've tried

<xsl:if test="/testData">

and

<xsl:if test="../testData">

Neither one works. I'm sure this is possible but I'm not sure how. :P

For context the XML file is laid out like this

<overall>
 <body/>
 <state/>
 <data/>(the one I want access to
 </overall>

I'm currently in the <body> tag, though I'd like to access it globally. Shouldn't /overall/data work?

Edit 2: Right now I have an index into data that I need to use at anytime when apply templates to the tags inside of body. How do I tell, while in body, that data exists? Sometimes it does, sometimes it doesn't. Can't really control that. :)

3
You should provide a concise XML sample. Your problem 90% percent is in misusing context. - Flack
aahh. I didn't escape my code. :P - bobber205
It depends on the context node. - Max Toro
"Neither one works" - this is a red flag saying "In what way doesn't it work?" Do you get an error? Incorrect result? If the latter, what was the expected result and the actual result? If you use an XPath expression starting with /, then the result doesn't depend on the context node (as long as you're in the right document). But it's hard to help you without knowing what you mean by "it doesn't work". - LarsH
Exact duplicate of xpath find if node exists - user357812

3 Answers

10
votes

Try count(.//testdata) &gt; 0.

However if your context node is textdata and you want to test whether it has somenode child or not i would write:

  <xsl:if test="somenode"> 
    ...
  </xsl:if>

But I think that's not what you really want. I think you should read on different techniques of writing XSLT stylesheets (push/pull processing, etc.). When applying these, then such expressions are not usually necessary and stylesheets become simplier.

4
votes

This XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="text()"/> <!-- for clarity only -->
    <xsl:template match="body">
        <xsl:if test="following-sibling::data">
            <xsl:text>Data occurs</xsl:text>
        </xsl:if>
        <xsl:if test="not(following-sibling::data)">
            <xsl:text>No Data occurs</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Applied to this sample:

<overall>
    <body/>
    <state/>
    <data/>(the one I want access to
</overall>

Will produce this correct result:

Data occurs

When applied to this sample:

<overall>
    <body/>
    <state/>
</overall>

Result will be:

No Data occurs
3
votes

This will work with XSL 1.0 if someone needs...

<xsl:choose>
    <xsl:when test="/testdata">node exists</xsl:when>
    <xsl:otherwise>node does not exists</xsl:otherwise>
</xsl:choose>