Reputation: 13
I have a xsl:template like this:
<xsl:template name="box2">
<xsl:param name="txt"/>
<div class="panel1">
<xsl:value-of select="$txt" disable-output-escaping="yes" />
</div>
</xsl:template>
then I call templete with param:
<xsl:call-template name="box2">
<xsl:with-param name="txt">
<b>First</b>
<b>Second</b>
</xsl:with-param>
</xsl:call-template>
result is like this:
<div class="panel1">
<b>First</b>
Second
</div>
I tried to use copy-of Instead value-of, then result is:
<div class="panel1">
<b>First</b>
<b>Second</b>
</div>
is a way to have result like this:
<div class="panel1">
<b>First</b>;
<b>Second</b>
</div>
Upvotes: 1
Views: 2142
Reputation: 167716
As http://www.w3.org/TR/xslt#copying shows, there is no disable-output-escaping
allowed on xsl:copy-of
. If you are using XSLT 1.0 then your parameter is a result tree fragment which you can convert to a node-set and then you can apply templates to the nodes where for text nodes you use value-of
with disable-output-escaping
while for element nodes you use copy-of
:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">
<xsl:template name="box2">
<xsl:param name="rtf"/>
<div class="panel1">
<xsl:apply-templates select="exsl:node-set($rtf)/node()" mode="doe"/>
</div>
</xsl:template>
<xsl:template match="text()" mode="doe">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="*" mode="doe">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="box2">
<xsl:with-param name="rtf">
<b>First</b>
<b>Second</b>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
</xsl:transform>
See http://xsltransform.net/jyH9rN9 for an example which outputs
<div class="panel1">
<b>First</b>
<b>Second</b></div>
Note that disable-output-escaping
is not supported in Mozilla browsers as it is an optional serialization feature while Gecko simply renders the XSLT result tree, it does not serialize it.
With XSLT 2.0 it is easier as you don't use exsl:node-set
, see http://xsltransform.net/nc4NzRb which does
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template name="box2">
<xsl:param name="fragment"/>
<div class="panel1">
<xsl:apply-templates select="$fragment/node()" mode="doe"/>
</div>
</xsl:template>
<xsl:template match="text()" mode="doe">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="*" mode="doe">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="box2">
<xsl:with-param name="fragment">
<b>First</b>
<b>Second</b>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
</xsl:transform>
In your comments you have added more complexity to the input you have, if you want to use the same approach then you can't simply take deep copies of element nodes, you need to take a shallow copy and process the child nodes the same way:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:for-each select="//root/cmnt">
<xsl:call-template name="box1">
<xsl:with-param name="rtf">
<b>
<xsl:value-of select="." />
</b>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="box1">
<xsl:param name="rtf"/>
<div>
<xsl:apply-templates select="msxsl:node-set($rtf)/node()" mode="doe"/>
</div>
</xsl:template>
<xsl:template match="text()" mode="doe">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="*" mode="doe">
<xsl:copy>
<xsl:apply-templates mode="doe"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2