The usual answer to the question “
how do I copy input XML elements into output XSLT stream?” is “
use xsl:copy or xsl:copy-of for deep copy.” But, as always, the devil is in the details. For example, if you're faced with a product catalog structure similar to this one …
<catalog>
<product id="123">
<name>Sample product</name>
<text>A <strong>marvellous</strong>
<span class='red'>red</span> book</text>
</product>
</catalog>
… and use a simplistic approach to the
copy-of …
<xsl:template match="product">
<h3><xsl:value-of select="name" /></h3>
<xsl:if test="text">
<xsl:copy-of select="text" />
</xsl:if>
</xsl:template>
… you'd end up with an extra non-HTML-compliant
text node in the output stream …
<h3>Sample product</h3>
<text>A <strong>marvellous</strong>
<span class="red">red</span> book </text>
To get just the contents you'd like to get, you should still use the
xsl:copy-of instruction, but select just the child element (
child::*) and the text nodes (
text()) of the
text element. To add icing on the cake, we'll enclose the contents of the
text element in a
P tag:
<xsl:template match="product">
<h3><xsl:value-of select="name" /></h3>
<xsl:for-each select="text">
<p><xsl:copy-of select="text() | child::*" /></p>
</xsl:for-each>
</xsl:template>
No comments:
Post a Comment