I am a beginner to the XSLT and I am a bit confused on how to use xsl:when
. Please find my sample XSLT code below with expected output and the actual output I am getting from the XSLT. Could you please suggest your solution and explain what I am doing incorrect while using xsl:when
.
XML
<source>
<bold>Hello, world.</bold>
<italic>fine.</italic>
<red>I am </red>
</source>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="source">
<xsl:choose>
<xsl:when test="bold">
<xsl:element name="p">
<xsl:element name="b">
<xsl:value-of select="bold"></xsl:value-of>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:when test="red">
<xsl:element name="p">
<xsl:value-of select="red"></xsl:value-of>
</xsl:element>
</xsl:when>
<xsl:when test="italic">
<xsl:element name="p">
<xsl:element name="i">
<xsl:value-of select="italic"></xsl:value-of>
</xsl:element>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="p">
<xsl:apply-templates/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
EXPECTED OUTPUT
<p><b>Hello, world.</b></p>
<p><i>fine.</i></p>
<p style="color:red;">I am </p>
ACTUAL OUTPUT
<p><b>Hello, world.</b></p>
To implement this using
xsl:choose
you could do something like:Note that here the template using
xsl:choose
matches the actual elements children ofsource
- unlike your attempt that took place at the parentsource
level.This means that each element tests itself (hence the use of the
self
axis) and itself only. Unlike your attempt, that tested the children ofsource
and returned true for the first test if any child ofsource
was<bold>
.Keep in mind that just because it is possible, it doesn't mean it's the best way to do it.
Note: Figuring out what your input XML would have been to produce the shown output given your XSLT was an unnecessary challenge, really. Please include the input in your question next time.
Explanation: When your template matches the
source
element,xsl:choose
finds only the firstxsl:when
condition whose test passes. A better organization to achieve your desired output would break thexsl:when
elements out into their ownxsl:templates
...Given this input XML:
This XSLT:
Will produce the requested output:
But you really should add this additional template:
To produce this well-formed output XML: