Check if node with attribute equals value exists

This should be working as you expect. One of your expressions (either in the variable's select or in the test attribute) must not be selecting what you think it is. (You haven't provided your full input, so it's hard to help there.)

Note a few things about xsl:if:

  • First, see this part of the XSLT spec (emphasis my own):

    The xsl:if element has a test attribute, which specifies an expression. The content is a template. The expression is evaluated and the resulting object is converted to a boolean as if by a call to the boolean function. If the result is true, then the content template is instantiated; otherwise, nothing is created.

  • So how would a call to the boolean function work on your input? See this part of the XPath spec (again, emphasis mine):

    The boolean function converts its argument to a boolean as follows :

    • a number is true if and only if it is neither positive or negative zero nor NaN

    • a node-set is true if and only if it is non-empty

    • a string is true if and only if its length is non-zero

    • an object of a type other than the four basic types is converted to a boolean in a way that is dependent on that type

So, if /contentdata/id actually selects an id for which /nodes/node[@id = $superid] returns a non-empty node-set, then the body of the xsl:if should execute.


If you are using the xpath expression /nodes/node[@id = $superid]"> then this would be looking for a root node of nodes in your XML document. However, in your question you seem to imply nodes is just a node within your document, not necessarily the root element. Try this instead

<xsl:if test="//nodes/node[@id = $superid]">Yes, Sir!</xsl:if>

The double-slash selects nodes in the document wherever they are in the hierarchy, not just the top-level node.


Use:

boolean(/nodes/node/@id = $superid)

Here is a complete transformation, showing this in action:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vDoe" select="'doe'"/>
 <xsl:variable name="vXyz" select="'xyz'"/>

 <xsl:template match="/">
     id attribute with value "doe' exists: <xsl:text/>
     <xsl:value-of select="boolean(/nodes/node/@id = $vDoe)"/>
==========
     id attribute with value "xyz' exists: <xsl:text/>
     <xsl:value-of select="boolean(/nodes/node/@id = $vXyz)"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<nodes>
    <node name="foo" id="bar" />
    <node name="john" id="doe" />
    <node name="jane" id="tarzan" />
</nodes>

the wanted, correct result is produced:

     id attribute with value "doe' exists: true
==========
     id attribute with value "xyz' exists: false

What you have seems to work for me (xsl 1.0) - as per here.

I've tried to recreate your xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />

    <xsl:template match="/xml">
        <xml>
            <xsl:apply-templates select="contentdata/id" />
        </xml>
    </xsl:template>

    <xsl:template match="id">
        <Result>
        <xsl:variable name="superid" select="."/>
        <SearchFor>
            <xsl:value-of select="$superid"/>
        </SearchFor>
        <IsPresent>
            <xsl:if test="/xml/nodes/node[@id = $superid]">Node is present</xsl:if>
        </IsPresent>
    </Result>
    </xsl:template>

</xsl:stylesheet>

Given the xml:

<xml>
    <contentdata>
        <id>doe</id>
        <id>unobtanium</id>
    </contentdata>
    <nodes>
        <node name='foo' id='bar' />
        <node name='john' id='doe' />
        <node name='jane' id='tarzan' />
    </nodes>
</xml>

Output:

<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Result>
        <SearchFor>doe</SearchFor>
        <IsPresent>Node is present</IsPresent>
    </Result>
    <Result>
        <SearchFor>unobtanium</SearchFor>
        <IsPresent />
    </Result>
</xml>