从值中截断字符后的属性总和

时间:2014-03-17 11:09:21

标签: xslt attributes sum

我有以下xml。

<xml>
  <table>
    <cols width="1.00*" />
    <cols width="2.00*" />
    <cols width="4.00*" />
       <row><p>Hello</p></row>          
  </table>
  <p>
     Life is good.
  </p>      
</xml>

阐释: 我需要从上面的xml中读取列宽并显示。但在某些情况下,用户指定的宽度应小于表格列相互重叠的宽度。 因此我想做这个公式。 col1width = col1width / totalWidth * 100; 这将以%格式提供表格宽度,以便正确分配列。 但我无法统计所有这些属性。我的xslt不起作用。请参阅下面的xslt:

XSLT:

<xsl:template match="node()" mode="table">
    <fo:table table-layout="fixed">
              <fo:table-header>
          <fo:table-row>
                    <xsl:for-each select="current()/cols">
                       <xsl:variable name="maxWidth"
                select="number(substring-before(current()/table/cols/@width, '*')) + number(substring-before(following-sibling::cols/@width, '*'))" />
                    </xsl:for-each>
                  </fo:table-row>
            </fo:table>

已尝试解决方案:

  1. 我尝试过使用sum函数。但在这里,在总结之前,我必须这样做 截断'*'字符并转换为数字然后添加。是否 不行。

  2. 编写一个递归模板来获取总和。我得到了这个总和。但是我无法返回总宽度 模板。我猜xslt不支持返回计算 值。下面是递归xslt。

       <xsl:template name="maximumTableWidth">
      <xsl:param name="total" select="0" />
      <xsl:param name="totalCols" />
      <xsl:param name="index" select="1" />
     <xsl:if test="$index &lt;= $totalCols">
       <xsl:variable name="maxWidth"
          select="$total + translate(current()/cols[$index]/@width, '*', '')" />   
    
                <xsl:call-template name="maximumTableWidth">
            <xsl:with-param name="total" select="$maxWidth" />
            <xsl:with-param name="nodes" select="$totalCols" />
            <xsl:with-param name="index" select="$index + 1" />
        </xsl:call-template>
      </xsl:if>
      </xsl:template>
    
  3. XSLT电话:

    <xsl:template name="main">   
      <xsl:variable name="maximumWidth">                
                <xsl:call-template name="maximumTableWidth">
                    <xsl:with-param name="total" select="0" />
                    <xsl:with-param name="totalCols"
                        select="count(current()/cols)" />
                </xsl:call-template>
            </xsl:variable>
     </xsl:template>
    

    这里,变量是string类型,因此没有值。 请帮我解决这个问题。也可以为表列宽度建议任何其他方法。我使用xsl fo生成pdf输出。而我的整个xslt都是动态的。我不能有像node1 / node2 / node3这样的直接路径。

    谢谢。

1 个答案:

答案 0 :(得分:2)

您的 maximumTableWidth 模板开始时遇到了一些问题。首先,您应该将translate函数包装在number函数

<xsl:variable name="maxWidth"
              select="$total + number(translate(current()/cols[$index]/@width, '*', ''))" />  

其次,您需要确保使用正确的参数调用它。对于递归调用,您应设置一个名为 nodes 的参数,当它应为 totalCols

<xsl:with-param name="totalCols" select="$totalCols" />

但就返回值而言,您需要使用 xsl:value-of 输出值,然后设置 maximumWidth 变量达到那个价值。您需要做的就是将模板中的 xsl:if 更改为 xsl:choose 并输出 xsl:otherwise 条件中的值:

<xsl:template name="maximumTableWidth">
    <xsl:param name="total" select="0" />
    <xsl:param name="totalCols" />
    <xsl:param name="index" select="1" />
    <xsl:choose>
        <xsl:when test="$index &lt;= $totalCols">
            <xsl:variable name="maxWidth"
            select="$total + number(translate(current()/cols[$index]/@width, '*', ''))" />   
            <xsl:call-template name="maximumTableWidth">
                <xsl:with-param name="total" select="$maxWidth" />
                <xsl:with-param name="totalCols" select="$totalCols" />
                <xsl:with-param name="index" select="$index + 1" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$total" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

还有另一种递归写入此模板的方法。不是传入索引并递增它,而是传递 cols 元素本身,并使用following-sibling迭代它们。请尝试使用此模板

<xsl:template name="maximumTableWidth">
    <xsl:param name="col" />
    <xsl:param name="total" select="0" />
    <xsl:choose>
        <xsl:when test="$col">
            <xsl:variable name="maxWidth"
            select="$total + number(translate($col/@width, '*', ''))" />   
            <xsl:call-template name="maximumTableWidth">
                <xsl:with-param name="total" select="$maxWidth" />
                <xsl:with-param name="col" select="$col/following-sibling::cols[1]" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$total" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

你会这样称呼:

    <xsl:variable name="maximumWidth">                
            <xsl:call-template name="maximumTableWidth">
                <xsl:with-param name="col" select="cols[1]" />
            </xsl:call-template>
     </xsl:variable>
    <xsl:value-of select="$maximumWidth" />

编辑:如果您能够使用XSLT 2.0,那么您可以完全取消命名模板,只需将 maximumWidth 模板设置为此

<xsl:variable name="maximumWidth" select="sum(cols/(number(translate(@width, '*', ''))))" />