7

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. :)

bobber205
  • 12,948
  • 27
  • 74
  • 100
  • You should provide a concise XML sample. Your problem 90% percent is in misusing context. – Flack Feb 09 '11 at 18:27
  • aahh. I didn't escape my code. :P – bobber205 Feb 09 '11 at 18:27
  • It depends on the context node. – Max Toro Feb 09 '11 at 18:44
  • "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 Feb 09 '11 at 19:36
  • Exact duplicate of [xpath find if node exists](http://stackoverflow.com/questions/767851/xpath-find-if-node-exists) –  Feb 09 '11 at 20:20
  • I get "false" no matter if it really exists or not for both. – bobber205 Feb 09 '11 at 20:24
  • @bobber205: Very badly formulated "question" -- you really deserve -1. Why are you wasting not only your own time but that of tens of readers? Learn. Improve. Correct. – Dimitre Novatchev Feb 09 '11 at 20:31
  • I am very ignorant on how XSL and Xpath work. I thought this was a reasonable question. :) – bobber205 Feb 09 '11 at 20:39

3 Answers3

10

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.

Alex Nikolaenkov
  • 2,505
  • 20
  • 27
  • 2
    The effective boolean value of an empty node set is `false`. No XSLT programmer use `count()` function for testing existence. –  Feb 09 '11 at 20:10
  • @Alejandro, thanks for pointing out. I'm not using XSLT actively for three or four years already. Will try to catch up :) – Alex Nikolaenkov Feb 09 '11 at 20:17
  • That's it! I was trying to do it with slash `test="/somenode"` and for some reason it doesn't work like that... – Ap0st0l Feb 08 '21 at 08:59
4

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
Flack
  • 5,862
  • 2
  • 23
  • 27
  • Ah. I should have said that the tags are all closed. See my latest edit. :) – bobber205 Feb 09 '11 at 20:37
  • Your sample is really weird. You need to match text node, which goes right after `data` element? – Flack Feb 09 '11 at 20:39
  • 1
    Downvoting, although OP stated that he added self-closing for these tags in an edit. Some people are just ignorant. – Flack Feb 15 '11 at 06:28
3

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>
Hrvoje Golcic
  • 3,446
  • 1
  • 29
  • 33