I have the following xml:
<fo:block font-weight="bold" font-style="italic">Some Text Here</fo:block>
I need to convert it to the following using xsl:
{\b\iSome Text Here\i0\b0\par}
So far i managed to select the block element using:
<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:apply-templates />
<xsl:text>\par}</xsl:text></xsl:template>
and i am outputting:{Some Text Here\par}
I am struggling with the attributes and inserting it using xsl, can anyone give me an example of selecting those attributes and getting the desired result?
There's a fairly simple way of doing this generically, using template modes, and the <xsl:sort> instruction.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:apply-templates select="@*" mode="prefix" />
<xsl:apply-templates select="node()" />
<xsl:apply-templates select="@*" mode="suffix">
<xsl:sort order="descending"/>
</xsl:apply-templates>
<xsl:text>\par}</xsl:text>
</xsl:template>
<xsl:template match="@font-weight['bold']" mode="prefix">\b</xsl:template>
<xsl:template match="@font-style['italic']" mode="prefix">\i</xsl:template>
<xsl:template match="@font-weight['bold']" mode="suffix">\b0</xsl:template>
<xsl:template match="@font-style['italic']" mode="suffix">\i0</xsl:template>
</xsl:stylesheet>
The <xsl:sort order="descending" /> processes the attributes in reverse order the second time, when the 'suffix' mode is used.
Strictly speaking the select="node()" in the middle of the main template is superfluous, but it makes it clearer when reading that only nodes are processed, and not attributes.
You could make it a little easier to add new attributes by replacing the existing suffix mode templates with this:
<xsl:template match="@*" mode="suffix">
<xsl:apply-templates select="." mode="prefix" />
<xsl:text>0</xsl:text>
</xsl:template>
This just uses the prefix's template, and adds the extra 0 on the end. You can always override it if some attributes can't be handled as generically as this.
<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:if test="@font-weight = 'bold'">\b</xsl:if>
<xsl:if test="@font-style = 'italic'">\i</xsl:if>
<xsl:apply-templates />
<xsl:if test="@font-style = 'italic'">\i0</xsl:if>
<xsl:if test="@font-weight = 'bold'">\b0</xsl:if>
<xsl:text>\par}</xsl:text>
</xsl:template/>
Also check w3schools.com for further readings on XSLT.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With