HTML Tags in XSLT Variables
Sometimes there is the need to show text inside HTML tags. For instance, in one occasion, I wanted to show just a portion of the contents in a Wiki field, but just the text. xsl:value-of will return the contents inside HTML tags:
1: <xsl:variable name="html">
2: This <div style="something"><span>is some</span> HTML <strong>contents</strong></div>
3: </xsl:variable>
4:
5: <xsl:value-of select="$html"/>
This will return “This is some HTML contents”.
If in the other hand you want to show the HTML contents as is, use xsl:copy-of instead:
1: <xsl:copy-of select="$html"/>
Which will return “This
is some HTML contents” (line break because of the DIV element).
However, if your variable is HTML encoded (> are >, < are <, etc), it’s a whole different matter. For that, you need to use a recursive template:
1: <xsl:template name="StripHtml">
2: <xsl:param name="html"/>
3: <xsl:choose>
4: <xsl:when test="contains($html, '&lt;')">
5: <xsl:value-of select="substring-before($html, '&lt;')"/>
6: <xsl:call-template name="StripHtml">
7: <xsl:with-param name="html" select="substring-after($html, '&gt;')"/>
8: </xsl:call-template>
9: </xsl:when>
10: <xsl:otherwise>
11: <xsl:value-of select="$html"/>
12: </xsl:otherwise>
13: </xsl:choose>
14: </xsl:template>
15:
16: <xsl:variable name="html_encoded">
17: This &lt;div&gt;&lt;span&gt;is some&lt;/span&gt; HTML &lt;strong&gt;contents&lt;/strong&gt;&lt;/div&gt;
18: </xsl:variable>
19:
20: <xsl:call-template name="StripHtml">
21: <xsl:with-param name="html" select="$html_encoded"/>
22: </xsl:call-template>
Will return “This is some HTML contents” as well. The logic is this:
- First, show anything before the first < (<), if it exists;
- Check if the parameter contains a <, and if so, call the template recursively passing as a parameter the text after > (>), which is supposed to exist;
- Otherwise, just output the parameter.