Reputation: 103
I'm putting together a simple XSL stylesheet so colleagues can preview XML that they are editing in their browser. One element has many different attribute values, each of which needs to be rendered differently.
<hi rend="b">
needs to be bold,
<hi rend="b i">
needs to be bold and italic, and so on.
What do I need to do in the XSL to make this happen?
I've done a good deal of Googling and haven't found a solution yet; perhaps it's a very basic question, but any help very gratefully received.
Upvotes: 0
Views: 39
Reputation: 163322
The solution from @zx485 requires 4 templates if there are 2 styles, 8 if there are 3, 16 if there are 4: that's not very scaleable.
For comparison here's an XSLT 3.0 solution (which you could run in Saxon-JS) that will handle a completely open-ended set of styles:
<xsl:function name="f:render" as="element()">
<xsl:param name="e" as="element()"/>
<xsl:param name="styles" as="xs:string*"/>
<xsl:choose>
<xsl:when test="empty($styles)">
<xsl:copy select="$e">
<xsl:copy-of select="@* except @rend"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{head($styles)}">
<xsl:sequence select="f:render($e, tail($styles))"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
then
<xsl:template match="*[@rend]">
<xsl:sequence select="f:render(., tokenize(@rend))"/>
</xsl:template>
Upvotes: 1
Reputation: 29022
Because you wrote your colleagues preview XML in their browser I assume that you expect an XSLT-1.0 solution. The following templates copy the hi
element and replaces the attribute with b
and i
tags. The copied hi
tags are ignored by the browser.
However, in this solution you have to create combinations of each attribute value.
<xsl:template match="hi[contains(@rend,'i')]">
<xsl:copy>
<i><xsl:apply-templates /></i>
</xsl:copy>
</xsl:template>
<xsl:template match="hi[contains(@rend,'b')]">
<xsl:copy>
<b><xsl:apply-templates /></b>
</xsl:copy>
</xsl:template>
<xsl:template match="hi[contains(@rend,'i') and contains(@rend,'b')]">
<xsl:copy>
<i><b><xsl:apply-templates /></b></i>
</xsl:copy>
</xsl:template>
Output:
<hi><i><b>
...3...
</b></i></hi>
<hi><i>
...1...
</i></hi>
<hi><b>
...2...
</b></hi>
Upvotes: 2