代码之家  ›  专栏  ›  技术社区  ›  robyp7

fo:表到html表-xslt

  •  0
  • robyp7  · 技术社区  · 10 年前

    我正在尝试编写xslt以生成另一个xslt,目的是用html标记仅替换所有xsl:fo。。XSLT 1

    我在“xsl”命名空间周围使用CDATA,以避免xslt处理此类标记。我的作用域仅处理xsl:fo指令并替换,例如:

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

    我想要translate fo:table+fo:table-body with table tag,fo:table-column with td width=“..%”,fo:table row with tr.td width不太容易检索,因为width属性属于fo:table column和fo:table单元格处理标记。

    当我读取正在写入td的表单元格时,我尝试循环fo:table列,并使用previous标记fo:table column获得的属性column width来计算宽度:我使用fo:table单元格选择中标记table列的position()(第一个循环)

    例如,这里是我的xslt tralslator for xsl:fo(如上所述):

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

    但我无法理解为什么所有td都包含“y”、“x”和“空”,因为它只属于空表单元格,似乎它读取了所有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>
    

    我需要获得:

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

    如果我替换第二个循环 xsl:for-each 具有

    xsl : template
    

    什么都不匹配! 也许*[$vPosition]不起作用,但如果我将数字替换为1或2,它就会起作用。。

    发生了什么?

    谢谢你的建议!

    罗比

    1 回复  |  直到 10 年前
        1
  •  0
  •   Tim C    10 年前

    问题是这条线。。。

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

    或者更确切地说,这是由于 vPosition 变量定义如下:

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

    通过使用 xsl:value-of 你实际上是 v位置 设置为字符串值,而不是数值。在条件中使用字符串值时,如 [*$vPosition] 如果该字符串不为空,则始终返回true。

    尝试将变量声明更改为this,这将设置 v位置 成为一个数字

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