计算和显示嵌套元素的总和 XSLT [英] Calculate and show sum from nested elements XSLT

查看:25
本文介绍了计算和显示嵌套元素的总和 XSLT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XML 是:

<row id="FOLDER1"><cell image="blank.gif">文件夹 1</cell><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><cell sum="1">$23</cell><row id="FOLDER2"><cell image="blank.gif">文件夹 2</cell><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><cell sum="2">$11</cell><row id="FOLDER3"><cell image="blank.gif">文件夹 3</cell><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><单元格></单元格><cell sum="3">$44</cell><row id="pro1"><cell image="blank.gif">产品 1</cell><单元格>324234</单元格><细胞>3.00</细胞><细胞>千</细胞><细胞>1.00</细胞><单元格>否</单元格><单元格>€ 33.33</单元格><单元格>€ 33.33</单元格></row><row id="pro2"><cell image="blank.gif">产品 2</cell><单元格>4354354</单元格><细胞>1.00</细胞><细胞>千</细胞><细胞>0.50</细胞><单元格>否</单元格><单元格>€2.53</单元格><单元格>€ 1.26</单元格></row></row><row id="pro3"><cell image="blank.gif">产品 3</cell><单元格>435436</单元格><细胞>10.00</细胞><细胞>千</细胞><单元格>是</单元格><单元格>€0.36</单元格><单元格>€ 3.60</单元格></row><row id="pro4"><cell image="blank.gif">产品 4</cell><单元格>435435</单元格><单元格>3.28</单元格><细胞>千</细胞><细胞>1.00</细胞><单元格>否</单元格><单元格>€17.38</单元格><单元格>€17.38</单元格></row><row id="NEWCAT_59"><cell image="blank.gif">&lt;strong>+添加新类别</strong></cell></row><row id="NEWSEMING_59"><cell image="blank.gif">&lt;strong>+添加新产品</strong></cell></row></row></row></rows>

XSLt 是:

<xsl:output method="html" indent="yes"/><xsl:strip-space elements="*"/><xsl:template match="/"><头/><身体><xsl:apply-templates select="rows"/></html></xsl:模板><xsl:template match="rows"><表格><tbody><tr><xsl:for-each select="row[1]/cell"><th><xsl:value-of select="position()"/></th></xsl:for-each></tr><xsl:apply-templates select="descendant::row"/></tbody></xsl:模板><xsl:template match="row[contains(cell[1],'Add new ')]"/><xsl:template match="row"><tr><xsl:apply-templates select="cell"/></tr></xsl:模板><xsl:模板名称=样式"><xsl:param name="margin" select="0"/><xsl:param name="display" select="'inline'"/><xsl:variable name="v1"><xsl:if test="$margin &gt; 0"><xsl:value-of select="concat('margin-left:',$margin,'px;')"/></xsl:if><xsl:if test="$display"><xsl:value-of select="concat('display: ',$display,';')"/></xsl:if></xsl:变量><xsl:if test="$v1"><xsl:attribute name="style"><xsl:value-of select="$v1"/></xsl:attribute></xsl:if></xsl:模板><xsl:template match="cell[position()=1][starts-with(../@id,'FOLDER')]" priority="3"><!-- FOLDER 行的第一列--><td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif"><xsl:call-template name="style"><xsl:with-param name="margin" select="(count(ancestor::row) - 1)*20"/><xsl:with-param name="display" select="''"/></xsl:call-template></img><xsl:value-of select="."/></td></xsl:模板><xsl:template match="cell[position()=1]" priority="2"><!-- 非文件夹行的第一列--><td><div><xsl:call-template name="style"><xsl:with-param name="margin" select="(count(ancestor::row) - 1)*20"/></xsl:call-template><xsl:value-of select="."/>

</td></xsl:模板><xsl:template match="cell" priority="1"><!-- 后续列--><td><div><xsl:call-template name="style"><xsl:with-param name="margin" select="20"/></xsl:call-template><xsl:value-of select="."/>

</td></xsl:模板></xsl:stylesheet>

我需要通过添加嵌套文件夹的最后一个单元格来计算总和.FOLDER1 而不是 $23,它应该有 23+11+44,FOLDER2 应该有 11+44,FOLDER3 只有 44,因为那里没有嵌套行.

预期输出为:

<头><META http-equiv="Content-Type" content="text/html; charset=utf-8"><身体><表格><tr>第 1 个第 2 个第 3 个第 4 个第 5 个第 6 个第 7 个第 8 个</tr><tr><td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="">文件夹 1</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">$78</div></td></tr><tr><td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="margin-left:20px;">文件夹 2<td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">$55</div></td></tr><tr><td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="margin-left:40px;">文件夹 3<td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">

</td><td><div style="margin-left:20px;display: inline;">$44</div></td></tr><tr><td><div style="margin-left:60px;display: inline;">Product 1</div></td><td><div style="margin-left:20px;display: inline;">324234</div></td><td><div style="margin-left:20px;display: inline;">3.00</div></td><td><div style="margin-left:20px;display: inline;">Kilo</div></td><td><div style="margin-left:20px;display: inline;">1.00</div></td><td><div style="margin-left:20px;display: inline;">否</div></td><td><div style="margin-left:20px;display: inline;">€ 33.33</div></td><td><div style="margin-left:20px;display: inline;">€ 33.33</div></td></tr><tr><td><div style="margin-left:60px;display: inline;">Product 2</div></td><td><div style="margin-left:20px;display: inline;">4354354</div></td><td><div style="margin-left:20px;display: inline;">1.00</div></td><td><div style="margin-left:20px;display: inline;">Kilo</div></td><td><div style="margin-left:20px;display: inline;">0.50</div></td><td><div style="margin-left:20px;display: inline;">否</div></td><td><div style="margin-left:20px;display: inline;">€2.53</div></td><td><div style="margin-left:20px;display: inline;">€ 1.26</div></td></tr><tr><td><div style="margin-left:40px;display: inline;">产品 3</div></td><td><div style="margin-left:20px;display: inline;">435436</div></td><td><div style="margin-left:20px;display: inline;">10.00</div></td><td><div style="margin-left:20px;display: inline;">Kilo</div></td><td><div style="margin-left:20px;display: inline;">Yes</div></td><td><div style="margin-left:20px;display: inline;">€ 0.36</div></td><td><div style="margin-left:20px;display: inline;">€ 3.60</div></td></tr><tr><td><div style="margin-left:40px;display: inline;">产品 4</div></td><td><div style="margin-left:20px;display: inline;">435435</div></td><td><div style="margin-left:20px;display: inline;">3.28</div></td><td><div style="margin-left:20px;display: inline;">Kilo</div></td><td><div style="margin-left:20px;display: inline;">1.00</div></td><td><div style="margin-left:20px;display: inline;">否</div></td><td><div style="margin-left:20px;display: inline;">€ 17.38</div></td><td><div style="margin-left:20px;display: inline;">€ 17.38</div></td></tr></tbody></html>

解决方案

将以下模板添加到您的样式表中,以便从当前的 XML 输入生成所需的结果.

<td><div><xsl:call-template name="sum"><xsl:with-param name="currentRow" select=".."/></xsl:call-template>

</td></xsl:模板><xsl:template name="sum"><xsl:param name="currentRow"/><xsl:param name="sum" select="0"/><xsl:when test="$currentRow//cell[@sum]"><xsl:call-template name="sum"><xsl:with-param name="currentRow"select="($currentRow//row[cell[@sum]])[1]"/><xsl:with-param name="sum"选择=$sum+"数字(翻译($currentRow/cell[@sum],'$',''))"/></xsl:call-template></xsl:when><xsl:否则><xsl:text>$</xsl:text><xsl:value-of select="$sum"/></xsl:否则></xsl:选择></xsl:模板>

The XML is:

<?xml version="1.0" encoding="UTF-8"?>
<rows>

  <row id="FOLDER1">
    <cell image="blank.gif">Folder 1</cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
    <cell></cell>
    <cell sum="1">$23</cell>
    <row id="FOLDER2">
      <cell image="blank.gif">Folder 2</cell>
      <cell></cell>
      <cell></cell>
      <cell></cell>
      <cell></cell>
      <cell></cell>
      <cell></cell>
      <cell sum="2">$11</cell>
      <row id="FOLDER3">
        <cell image="blank.gif">Folder 3</cell>
        <cell></cell>
        <cell></cell>
        <cell></cell>
        <cell></cell>
        <cell></cell>
        <cell></cell>
        <cell sum="3">$44</cell>
        <row id="pro1">
          <cell image="blank.gif">Product 1</cell>
          <cell>324234</cell>
          <cell>3.00</cell>
          <cell>Kilo</cell>
          <cell>1.00</cell>
          <cell>No</cell>
          <cell>€ 33.33</cell>
          <cell>€ 33.33</cell>
        </row>
        <row id="pro2">
          <cell image="blank.gif">Product 2</cell>
          <cell>4354354</cell>
          <cell>1.00</cell>
          <cell>Kilo</cell>
          <cell >0.50</cell>
          <cell>No</cell>
          <cell>€ 2.53</cell>
          <cell>€ 1.26</cell>
        </row>

      </row>
      <row id="pro3">
        <cell image="blank.gif">Product 3</cell>
        <cell>435436</cell>
        <cell>10.00</cell>
        <cell>Kilo</cell>
        <cell>Yes</cell>
        <cell>€ 0.36</cell>
        <cell>€ 3.60</cell>
      </row>

    <row id="pro4">
      <cell image="blank.gif">Product 4</cell>
      <cell>435435</cell>
      <cell>3.28</cell>
      <cell>Kilo</cell>
      <cell>1.00</cell>
      <cell>No</cell>
      <cell>€ 17.38</cell>
      <cell>€ 17.38</cell>
    </row>
    <row id="NEWCAT_59">
        <cell image="blank.gif">&lt;strong&gt;+ Add new category&lt;/strong&gt;</cell>
      </row>
      <row id="NEWSEMING_59">
        <cell image="blank.gif">&lt;strong&gt;+ Add new product&lt;/strong&gt;</cell>
      </row>
   </row>
  </row>

</rows>

The XSLt is:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*" />

<xsl:template match="/">
  <html>
    <head/>
    <body>
      <xsl:apply-templates select="rows" />
    </body>
  </html>
</xsl:template>

<xsl:template match="rows">
  <table>
    <tbody><tr>
      <xsl:for-each select="row[1]/cell">
        <th><xsl:value-of select="position()" /></th>
      </xsl:for-each>
    </tr>
    <xsl:apply-templates select="descendant::row" />  
  </tbody>
  </table>
</xsl:template>  

<xsl:template match="row[contains(cell[1],'Add new ')]" />

<xsl:template match="row">
  <tr>
    <xsl:apply-templates select="cell" />
  </tr>  
</xsl:template>

<xsl:template name="style">
  <xsl:param name="margin" select="0" />
  <xsl:param name="display" select="'inline'" />
  <xsl:variable name="v1">
    <xsl:if test="$margin &gt; 0">
      <xsl:value-of select="concat('margin-left:',$margin,'px;')" />
    </xsl:if>
    <xsl:if test="$display">
      <xsl:value-of select="concat('display: ',$display,';')" />
    </xsl:if>
  </xsl:variable>  
  <xsl:if test="$v1">
    <xsl:attribute name="style"><xsl:value-of select="$v1" /></xsl:attribute>
  </xsl:if>
</xsl:template>

<xsl:template match="cell[position()=1][starts-with(../@id,'FOLDER')]" priority="3">
  <!-- First column for FOLDER rows -->
  <td>
    <img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif">
      <xsl:call-template name="style">
        <xsl:with-param name="margin" select="(count(ancestor::row) - 1)*20" />
        <xsl:with-param name="display" select="''" />
       </xsl:call-template>
     </img>
  <xsl:value-of select="." />
  </td>  
</xsl:template>

<xsl:template match="cell[position()=1]" priority="2">
  <!-- First column for non-FOLDER rows -->
  <td>
     <div>
      <xsl:call-template name="style">
        <xsl:with-param name="margin" select="(count(ancestor::row) - 1)*20" />
       </xsl:call-template>
       <xsl:value-of select="." />
     </div>
  </td>  
</xsl:template>

<xsl:template match="cell" priority="1">
  <!-- Subsequent columns -->
  <td>
     <div>
      <xsl:call-template name="style">
        <xsl:with-param name="margin" select="20" />
       </xsl:call-template>
       <xsl:value-of select="." />
     </div>
  </td>  
</xsl:template>

</xsl:stylesheet>

I need to calculate the sum by adding nested folder's last cells. FOLDER1 instead of $23 it should have 23+11+44,FOLDER2 should have 11+44 and FOLDER3 just 44 because there aren't nested rows there.

The expected output is:

<html>
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <table>
      <tbody>
        <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
          <th>6</th>
          <th>7</th>
          <th>8</th>
        </tr>
        <tr>
          <td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="">Folder 1</td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">$78</div>
          </td>
        </tr>
        <tr>
          <td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="margin-left:20px;">Folder 2</td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">$55</div>
          </td>
        </tr>
        <tr>
          <td><img alt="neso" src="http://www.deporteandaluz.com/web/includes/dhtmlx/imgs/csh_winstyle/minus.gif" style="margin-left:40px;">Folder 3</td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">
            </div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">$44</div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="margin-left:60px;display: inline;">Product 1</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">324234</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">3.00</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">Kilo</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">1.00</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">No</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 33.33</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 33.33</div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="margin-left:60px;display: inline;">Product 2</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">4354354</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">1.00</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">Kilo</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">0.50</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">No</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 2.53</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 1.26</div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="margin-left:40px;display: inline;">Product 3</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">435436</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">10.00</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">Kilo</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">Yes</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 0.36</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 3.60</div>
          </td>
        </tr>
        <tr>
          <td>
            <div style="margin-left:40px;display: inline;">Product 4</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">435435</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">3.28</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">Kilo</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">1.00</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">No</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 17.38</div>
          </td>
          <td>
            <div style="margin-left:20px;display: inline;">€ 17.38</div>
          </td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

解决方案

Add the following templates to your stylesheet in order to produce the desired result from the current XML input.

<xsl:template match="cell[@sum]" priority="1.5">
    <td>
        <div>
            <xsl:call-template name="sum">
                <xsl:with-param name="currentRow" select=".." />
            </xsl:call-template>
        </div>
    </td>  
</xsl:template>

<xsl:template name="sum">
    <xsl:param name="currentRow" />
    <xsl:param name="sum" select="0"/>
    <xsl:choose>
        <xsl:when test="$currentRow//cell[@sum]">
            <xsl:call-template name="sum">
                <xsl:with-param name="currentRow" 
                                select="($currentRow//row[cell[@sum]])[1]" />
                <xsl:with-param name="sum" 
                                select="$sum+
                                        number(
                                          translate(
                                            $currentRow/cell[@sum], 
                                            '$',
                                            ''))"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>$</xsl:text>
            <xsl:value-of select="$sum"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

这篇关于计算和显示嵌套元素的总和 XSLT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆