Jump to content

XSLT to generate another XSLT script (source xsl:fo)


Recommended Posts



I'm trying to write an xslt to generate another xslt that purpose is replacing only all xsl:fo with html tags..XSLT 1

I use <![CDATA[ around "xsl:" namespace for avoid processing this kind of tag by the xslt. My scope is processing only xsl:fo directive and replace for example :


<fo:table table-layout="fixed" width="100%" font-size="10pt"> <fo:table-column column-width="proportional-column-width(0.65)"/> <fo:table-column column-width="proportional-column-width(0.35)"/> <fo:table-body> <fo:table-row> <fo:table-cell padding-before="0.5cm"></fo:table-cell> <fo:table-cell padding-before="0.5cm"> <fo:block> y

<![CDATA[ --> this is treated as text so i can copy it with <xsl-valueof select="."/>??

<xsl:choose> <xsl:when test="...xpath'"> <xsl:value-of select="..." />, </xsl:when> <xsl:otherwise> at <xsl:value-of select=..." />, </xsl:otherwise> </xsl:choose>]]> </fo:block> <fo:block space-before="0.5cm" text-align="center"> x </fo:block> </fo:table-cell> </fo:table-row> </fo:table-body> </fo:table>


I want traslate fo:table+fo:table-body with <table>, and fo:table-column with <td width="..%">, fo:table-row with <tr>.. Td width is not so easy to retrieve because the width property belong to fo:table-column and fo:table-cell handling the <td> tag.

I try to loop fo:table-column when i read a table-cell i'm writing td and calculate the width using the property column-width obtained by precedent tag fo:table-column: i use the position() of tag table-column (first loop) in the fo:table-cell selection


for example here is my xslt tralslator for xsl:fo (above-mentioned):


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo fn" xmlns:fn="http://www.w3.org/2005/xpath-functions " ><xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" indent="yes"/>


...rendering html body ecc



<!-- rendering a fo:table-->

<xsl:template name="fo-table"> <xsl:param name="font-size" /> <xsl:param name="width" /> <xsl:variable name="cols" select="count(fo:table-column)"/> <!-- fo:columns e fo:table-cell di pari numero --> <xsl:if test="fo:table-column"> <xsl:variable name="effective-cols" select="count(fo:table-body/fo:table-row/fo:table-cell)"/> <xsl:if test="$cols = $effective-cols"> <table> <xsl:for-each select="fo:table-body/fo:table-row"> <tr> <xsl:for-each select="parent::*/parent::*/fo:table-column"><!-- xsl:for-each select="fo:table-cell" --> <xsl:variable name="width-proportional"> <xsl:value-of select="@column-width"/> </xsl:variable> <td> <xsl:attribute name="width"> <xsl:call-template name="getPercentWidth"> <xsl:with-param name="proportional-value-width"><xsl:value-of select="$width-proportional"/></xsl:with-param> </xsl:call-template> </xsl:attribute> abc <xsl:variable name="vPosition"><xsl:value-of select="position()"/></xsl:variable> <xsl:for-each select="parent::*/fo:table-body/fo:table-row/*[$vPosition]"> <xsl:value-of select="local-name()"/><xsl:text> #10;</xsl:text> <!-- debug--> <xsl:choose> <xsl:when test="fo:block"> <xsl:for-each select="fo:block"> <xsl:call-template name="fo-block-table"> <xsl:with-param name="text-align"><xsl:value-of select="@text-align"/></xsl:with-param> <xsl:with-param name="space-before"><xsl:value-of select="@space-before"/></xsl:with-param> </xsl:call-template> </xsl:for-each> </xsl:when> <xsl:otherwise> empty cell </xsl:otherwise> </xsl:choose> </xsl:for-each> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:if> </xsl:if> </xsl:template>


<xsl:template name="fo-block-table"> <xsl:param name="text-align" /> <xsl:param name="space-before" /> <xsl:choose> <xsl:when test="$text-align"> <!-- costruisce <p text-align=""> --> <div> <xsl:attribute name="text-align"> <xsl:value-of select="normalize-space($text-align)"/> </xsl:attribute> <xsl:apply-templates select="."/> </div> </xsl:when> <xsl:otherwise> <div> <xsl:apply-templates select="."/> </div> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- from proportional width to % width of table td --> <xsl:template name="getPercentWidth"> <xsl:param name="proportional-value-width"/> <xsl:variable name="width" select="normalize-space($proportional-value-width)"/> <xsl:variable name="begin"> <xsl:value-of select="string-length(substring-before($width, '('))" /></xsl:variable> <xsl:variable name="last"> <xsl:value-of select="string-length(substring-before($width,')'))" /></xsl:variable> <xsl:variable name="val" select="fn:substring($width, $begin, $last)" /> <xsl:variable name="val1" select="substring-after($val,'(')"/> <xsl:variable name="cent" select="100"/> <xsl:value-of select="concat(($val1 * $cent),'%')"/> </xsl:template>

But i cant realize why all td's contains 'y',x and empty when it will belong only to the empty table-cell, seems it reads all fo:block..


<table><tr><td width="65%"> abc table-cell #10; empty cell table-cell #10;<div> y </div><div text-align="center"> x </div></td><td width="35%"> abc table-cell #10; empty cell table-cell #10;<div> y </div><div text-align="center"> x </div></td></tr></table>


I need to obtain:



<table><tr><td width="65%"> abc table-cell #10; empty cell </td><td width="35%"> abc table-cell #10;

<div> y </div> <div text-align="center"> x </div></td></tr></table>


if i replace <xsl:for-each select="parent::*/fo:table-body/fo:table-row/*[$vPosition]">


<xsl:template match="parent::*/fo:table-body/fo:table-row/*[$vPosition]">


don't match anything!


Maybe *[$vPosition] doesn't work but it works if i replace number like 1 or 2..


What's wrong?


Thanks in advice!



Edited by robyp1
Link to comment
Share on other sites

OK i found by myself!


The problem is with this line:<xsl:for-each select="parent::*/fo:table-body/fo:table-row/*[$vPosition]">Or rather, it is due to how the vPosition variable is defined:<xsl:variable name="vPosition"><xsl:value-of select="position()"/></xsl:variable>By using xsl:value-of you are actually causing vPosition to be set to a string value, not a numeric value. When you use a string value in a condition, like [*$vPosition] it will always return true if that string is not empty.so, i change the variable declaration to this, which will set vPosition to be a number!<xsl:variable name="vPosition" select="position()" />

Edited by robyp1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...