Re: Using xsl:if to determine if a node is empty.

Subject: Re: Using xsl:if to determine if a node is empty.
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 15 Oct 2000 19:19:40 +0100
Roger,

You're trying to test here whether the VENDOR_ITEM_NUM element is an empty
element or not - in other words does it have any child nodes.

You can form a node set that holds the child nodes of the current node (the
VENDOR_ITEM_NUM element using the XPath:

  child::node()

Note however, that this will get *any* node in the content of the element:
elements, text, processing instructions and even comments.  Probably you
want to limit this to only elements and text nodes that consist of more
than just whitespace:

  child::text()[normalize-space(.)] | child::*

or, shorter:

  text()[normalize-space(.)] | *

These XPaths actually tell you whether the element has any content.  In
fact, VENDOR_ITEM_NUM probably only takes text children anyway, and it's
only their value that you care about.  If you are interested in whether the
VENDOR_ITEM_NUM element has some textual content that isn't just whitespace
you can get the nodes that make up that text using just:

  text()[normalize-space(.)]

If you just run a test on that node set, then you will get 'true' if there
are any nodes in the node set, and 'false' if there aren't.  But in a test
like this, then you can alternatively test whether the current node has a
'string value' (which is formed by concatenating together the string values
of all the text and element child nodes), so you can use:

  normalize-space(.)

So try:

<xsl:template match="VENDOR_ITEM_NUM">	
  <tr>
    <td></td>
    <td>
      <font size="2">
        <xsl:if test="normalize-space(.)">
          <xsl:value-of select="concat('Vendor Item number: ',.)"/>
        </xsl:if>
      </font>
    </td>
  </tr>
</xsl:template>

If you want to use a variable to hold an empty string to test against, you
should probably define it as:

  <xsl:variable name="empty_string" select="''" />

as this creates an empty *string* rather than an empty 'result tree fragment'.

You should then be able to test with it as in:

<xsl:template match="VENDOR_ITEM_NUM">	
  <tr>
    <td></td>
    <td>
      <font size="2">
        <xsl:if test="normalize-space(.) != $empty_string">
          <xsl:value-of select="concat('Vendor Item number: ',.)"/>
        </xsl:if>
      </font>
    </td>
  </tr>
</xsl:template>

but don't forget to normalize-space() the content of the element, just to
get rid of any whitespace that might be lurking around.

I hope that this helps,

Jeni

Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread