If you're interested in functional programming, you might also want to checkout my second blog which i'm actively working on!!

Thursday, June 4, 2009

escaping html with xslt

Ok... suppose you get some xml from a customer which looks like:
<footnote>
<![CDATA[T<sup>j</sup> >= 25]]>
</footnote>

You could easily use the attribute disable-output-escaping if you only needed to put the value between a <td>. But what if you needed to transform it into something like

<td>
<a href="#footnote-1">T<sup>j</sup> >= 25</a>
</td>

In this case your last stylesheet can't have a matching template like the one below since that would mean getting rid of the anchor tag.
<xsl:template match="td">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

So when you KNOW what part of the xml can contain html tags, you can surround that data with a meta tag which you will use in the final transformation before serializing to xhtml.

So let's transform the above snippet to:

<footnote>
<nxp:escape>T<sup>j</sup> >= 25</nxp:escape>
</footnote>

<xsl:template match="footnote">
<td>
<a href="#footnote-{position()}"><xsl:apply-templates select=./node()/></a>
</td>
</xsl:template>


<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

So now we get

<td>
<a href="#footnote-1">
<nxp:escape>T<sup>j</sup> >= 25</nxp:escape>
</a>
</td>

In our last stylesheet we only need to to the following:

<xsl:template match="nxp:escape">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

Cheers,
Robby

No comments:

Post a Comment