Reputation: 1285
Tags can be outputted by either directly typing
<div>
<span>complex...</span>
</div>
or using <xsl:element>
,
<xsl:element name="div">
<span>complex...</span>
</xsl:element>
My question is how to do this: when x, output <div>
, when y, output <a>
, when z, output no tag?
One of course can make three templates, or even write ugly code as
<xsl:when ...x >
<![CDATA[ <div> ]]>
</xsl:when>
<span>complex...</span>
<xsl:when ...x >
<![CDATA[ </div> ]]>
</xsl:when>
but is there a way to conditionally provide the value of the name attribute of xsl:element?
I tried this, failed:
<xsl:variable name="a" select="'div'"/>
<xsl:element name="$a">
...
[edited] Forgot to say, XSLT1.0 only
Upvotes: 2
Views: 3230
Reputation: 117043
Here's another way to look at it:
<xsl:variable name="content">
<span>complex...</span>
</xsl:variable>
<xsl:choose>
<xsl:when ... x>
<div>
<xsl:copy-of select="$content"/>
</div>
</xsl:when>
<xsl:when ... y>
<a>
<xsl:copy-of select="$content"/>
</a>
</xsl:when>
<xsl:when ... z>
<xsl:copy-of select="$content"/>
</xsl:when>
</xsl:choose>
Upvotes: 2
Reputation: 163418
XSLT doesn't output tags: it outputs nodes to a result tree. Your suggestion of using constructs like <![CDATA[ </div> ]]>
is therefore way off the mark: you can't add half a node to a tree.
However, there's no difficulty with conditional generation of elements nodes. If you want to create an element but compute its name conditionally, then in XSLT 2.0 you can do
<xsl:element name="{if (test) then 'a' else 'b'}">
or if you're stuck with 1.0, the much more verbose
<xsl:variable name="elname">
<xsl:choose>
<xsl:when test="test">a</xsl:when>
<xsl:otherwise>b</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$elname}"/>
If you want to output an element or nothing depending on a condition, just do
<xsl:if test="test2">
<e/>
</xsl:if>
Upvotes: 0
Reputation: 4238
The name
attribute is not expecting a full-fledge XPath expression but simply a string. So, instead of using name="$a"
you only have to evaluate the Xpath expression into a string by bracing it with curly braces:
<xsl:element name="{$a}">
As for the conditional creation of the surrounding tag you could do something like this:
<xsl:variable name="tag_name">
<xsl:choose>
<xsl:when test="x">
<xsl:text>div</xsl:text>
</xsl:when>
<xsl:when test="y">
<xsl:text>a</xsl:text>
</xsl:when>
</xsl:choose>
<!-- possibly other checks for different tag names -->
<xsl:variable>
<xsl:choose>
<xsl:when test="$tag_name != ''">
<xsl:element name="$tag_name">
<!-- whatever has to be put into a tagged block (A) -->
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- whatever has to be put into a untagged block (B) -->
</xsl:otherwise>
</xsl:choose>
If A
and B
are equal you could put that into a template.
Upvotes: 1