Empty elements in XSLT
I recently wanted to deal with docbook <ulink> elements that didn't have any contents by displaying the url as the link text. I wanted to convert:
<ulink url="http://www.example.com">Example.com<ulink> <ulink url="http://www.example.com"/>
to
<a href="http://www.example.com">Example.com<a> <a href="http://www.example.com">http://www.example.com<a>
I originally had:
<xsl:template match="ulink">
<xsl:element name="a">
<xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
This sucessfully dealt with the first form of <ulink> that had content, but not with the second example with an empty element. The solution is the use an <xsl:choose> element with a test to see if the current node has any child nodes. Using child::node() we can get any child nodes. We can then test if the node has any children using the count() function. The resulting xslt is:
<xsl:template match="ulink">
<xsl:element name="a">
<xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>
<xsl:choose>
<xsl:when test="count(child::node())">
<xsl:apply-templates/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@url"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>