Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert xml using xslt

Tags:

xml

xslt

xsl-fo

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?

like image 615
stoic Avatar asked Jul 21 '26 15:07

stoic


2 Answers

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.

like image 161
Flynn1179 Avatar answered Jul 24 '26 03:07

Flynn1179


<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.

like image 31
Andreas Krueger Avatar answered Jul 24 '26 05:07

Andreas Krueger