【问题标题】:Addind values over loop in FOP with XSL and XML使用 XSL 和 XML 在 PHP 中循环添加值
【发布时间】:2017-07-13 20:53:45
【问题描述】:

我有这个 XML 和 XSL 示例:

XML:

<mastercount>
  <sourceval>
    <attm>50</attm>
    <fh>6500</fh>
    <id>1</id>
  </sourceval>
  <sourceval>
    <attm>15</attm>
    <fh>2300</fh>
    <id>2</id>
  </sourceval>
  <sourceval>
    <attm>4</attm>
    <fh>280</fh>
    <id>3</id>
  </sourceval>
  <sourceval>
    <attm>20</attm>
    <fh>2700</fh>
    <id>4</id>
  </sourceval>
</mastercount>

XSL:

<xsl:variable name="var_idx">
  <xsl:value-of select="position()" />
</xsl:variable>
<xsl:variable name="var_sum_attm" />
<xsl:variable name="var_sum_fh" />
<fo:table-row>
    <xsl:for-each select="/mastercount">
        <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right">
            <fo:block>
                <xsl:value-of select="sourceval[position()=$var_idx]/attm" />               
            </fo:block>     
        </fo:table-cell>

        <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right">
            <fo:block>
                <xsl:value-of select="sourceval[position()=$var_idx]/fh" />
            </fo:block>
        </fo:table-cell>
    </xsl:for-each>
</fo:table-row>

这部分源代码效果很好,我明白了

         attm  fh   attm    fh
 Val2     50 6500    0    6500 
 Val1     15 2300    0    2300 
 Val3    280    0  280       0 
 Val4     20 2700    0    2700 

(我在源代码中跳过了上面的名称部分)

但是我现在需要这两个字段的总和:

         attm  fh   attm    fh
 Val2     50 6500    0    6500 
 Val1     15 2300    0    2300 
 Val3    280    0  280       0 
 Val4     20 2700    0    2700
        sum   sum  sum     sum

我怎样才能让它工作?

有什么想法吗?

感谢您的帮助。 流浪汉

更新:

感谢 RT72,这是一个答案:

<xsl:for-each select="/mastercount">
    <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right">
      <fo:block>
        <xsl:value-of select="sum(sourceval/attm)"/>                                            
      </fo:block>                                       
    </fo:table-cell>
    <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right">
      <fo:block>
        <xsl:value-of select="sum(sourceval/fh)" />
      </fo:block>
    </fo:table-cell>
</xsl:for-each>

【问题讨论】:

    标签: xml pdf xslt xsl-fo apache-fop


    【解决方案1】:

    使用反映源结构的xsl:templates 并让 XSLT 处理器确定要处理的内容会更简单。下面的示例在模板中对mastercount 进行求和,sourceval 以及attmfh 的模板生成各自的 FO:

    <xsl:attribute-set name="table-cell">
        <xsl:attribute name="padding">3pt</xsl:attribute>
        <xsl:attribute name="border-style">solid</xsl:attribute>
        <xsl:attribute name="width">12mm</xsl:attribute>
        <xsl:attribute name="border-width">1pt</xsl:attribute>
        <xsl:attribute name="text-align">right</xsl:attribute>
    </xsl:attribute-set>
    
    <xsl:template match="mastercount">
        <fo:table>
            <fo:table-body>
                <xsl:apply-templates />
                <fo:table-row>
                    <fo:table-cell xsl:use-attribute-sets="table-cell">
                        <fo:block>
                            <xsl:value-of select="sum(sourceval/attm)" />
                        </fo:block>
                    </fo:table-cell>
                    <fo:table-cell xsl:use-attribute-sets="table-cell">
                        <fo:block>
                            <xsl:value-of select="sum(sourceval/fh)" />
                        </fo:block>
                    </fo:table-cell>
                </fo:table-row>
            </fo:table-body>
        </fo:table>
    </xsl:template>
    
    <xsl:template match="sourceval">
        <fo:table-row>
            <xsl:apply-templates select="attm | fh"/>
        </fo:table-row>
    </xsl:template>
    
    <xsl:template match="attm | fh">
        <fo:table-cell xsl:use-attribute-sets="table-cell">
            <fo:block>
                <xsl:apply-templates />
            </fo:block>
        </fo:table-cell>
    </xsl:template>
    

    如果您只想拥有一个模板来生成具有所需属性的fo:table-cell,您可以将mastercountattmfh 的模板更改为:

    <xsl:template match="mastercount">
        <fo:table>
            <fo:table-body>
                <xsl:apply-templates />
                <fo:table-row>
                    <xsl:call-template name="table-cell">
                        <xsl:with-param name="value" select="sum(sourceval/attm)" />
                    </xsl:call-template>
                    <xsl:call-template name="table-cell">
                        <xsl:with-param name="value" select="sum(sourceval/fh)" />
                    </xsl:call-template>
                </fo:table-row>
            </fo:table-body>
        </fo:table>
    </xsl:template>
    
    <xsl:template match="attm | fh" name="table-cell">
        <xsl:param name="value" select="." />
    
        <fo:table-cell xsl:use-attribute-sets="table-cell">
            <fo:block>
                <xsl:value-of select="$value" />
            </fo:block>
        </fo:table-cell>
    </xsl:template>
    

    【讨论】:

      【解决方案2】:

      以下内容应该适合您:

       <xsl:variable name="var_sum_attm" select="sum(/mastercount/sourceval/attm)"/>
       <xsl:variable name="var_sum_fh" select="sum(/mastercount/sourceval/fh)"/>
      

      在 OP 编辑​​问题后更新

      试试这个

      <xsl:for-each select="/mastercount/sourceval">
      <fo:table-row>                              
          <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right"> 
              <fo:block>
                  <xsl:value-of select="attm" />
              </fo:block>
          </fo:table-cell>
          <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right"> 
              <fo:block>
                  <xsl:value-of select="fh" />
               </fo:block>
           </fo:table-cell>
      </fo:table-row>
      

      <fo:table-row>                              
      <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right"> 
          <fo:block>
               <xsl:value-of select="sum(/mastercount/sourceval/attm)" />
          </fo:block>
      </fo:table-cell>
      <fo:table-cell padding="3pt" border-style="solid" width="12mm" border-width="1pt" text-align="right"> 
          <fo:block>
              <xsl:value-of select="sum(/mastercount/sourceval/fh)" />
           </fo:block>
       </fo:table-cell>
      </fo:table-row>
      

      【讨论】:

      • 按照 sum(/mastercount/sourceval/attm) 的行查看我编辑的答案。这将为您提供完整的总数
      • 由于某种原因我没有显示总和,表格字段在那里并且正确但它们是空的
      • 您需要将变量声明放在您的 for-each 之外
      • 我工作,但它需要第一个数字添加它们并始终使用它们。它会添加每列的数字并仅在此处使用它们
      • @Thevagabond 仅供参考,因为您已经访问了所需的所有节点信息,所以您不需要总数的 for-each - 您可能想看看我的最新更新,因为它提供了恕我直言对于详细信息行和摘要行都是更有效的解决方案,我认为您使用的位置内容和 var_idx 变量不是必需的
      【解决方案3】:

      你也可以用这个

          <xsl:value-of select="sum(for $i in //attm return $i)"/>
          <xsl:value-of select="sum(for $i in //fh return $i)"/>
      

      【讨论】:

      • 我得到一个错误,它是预期的,但是 $ 被发现了,我如何在循环之外得到 $i,因为我需要表格之后的总和行而不是每一行之后?跨度>
      • 您可以从表外调用此值,只需将 xpath //attm 更改为 mastercount/sourceval/attm
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 1970-01-01
      • 2011-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-26
      相关资源
      最近更新 更多