0
votes

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 tag, 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 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:template name="fo-table">
<xsl:param name="font-size" />
<xsl:param name="width" />
<xsl:variable name="cols" select="count(fo:table-column)"/> 
<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: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">
                <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>



   <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 the second loop xsl : for-each with

xsl : template

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!

Roby

1

1 Answers

0
votes

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.

Try changing the variable declaration to this, which will set vPosition to be a number

<xsl:variable name="vPosition" select="position()" />