【问题标题】:XSLT 1.0 Group and Sum by valuesXSLT 1.0 按值分组和求和
【发布时间】:2018-04-11 14:03:10
【问题描述】:

我正在尝试进行分组和求和。我有这个 xml:

<articles>
<group>
  <code>1000</code>
  <description>GROUP A</description>
  <article>
    <code>2600</code>
    <description>Article A</description>        
    <qty>14.00</qty>
    <amount>14.00</amount>        
    <menu_code>true</menu_code>
  </article>
  <article>
    <code>2600</code>
    <description>Article A</description>
    <qty>10.00</qty>
    <amount>0.00</amount>        
    <menu_code>true</menu_code>
  </article>
  <article>
    <code>2600</code>
    <description>Article A</description>
    <qty>1.00</qty>
    <amount>1.00</amount>        
    <menu_code>false</menu_code>
  </article>
</group>
<group>
  <code>2000</code>
  <description>GROUP B</description>
  <article>
    <code>2600</code>
    <description>Article B</description>        
    <qty>28.00</qty>
    <amount>28.00</amount>        
    <menu_code>true</menu_code>
  </article>
  <article>
    <code>2600</code>
    <description>Article B</description>
    <qty>10.00</qty>
    <amount>27.00</amount>        
    <menu_code>false</menu_code>
  </article>
  <article>
    <code>2600</code>
    <description>Article B</description>
    <qty>4.00</qty>
    <amount>8.00</amount>        
    <menu_code>false</menu_code>
  </article>
</group>

有了这些数据,我需要显示如下内容:

甲组

A 条数量:24 总:14.00

A 条* 数量:1 总计:1.00

B组

B 条数量:28 总:28.00

B 条* 数量:14 总计:35.00

显示按组排序的数据(文章/组) 然后显示文章描述(article/description),数量总和(sum(qty))和总和(sum(amount))。 如果文章有(article/menu_code = true),则显示在另一行,与false(*)隔开

希望你能帮助我,谢谢!

【问题讨论】:

  • 你尝试了什么?

标签: xml xslt sum


【解决方案1】:

在 XSLT 1.0 中,可以通过称为Muenchian Grouping 的技术来实现分组。

在您的示例中,由于要根据 &lt;description&gt;&lt;menu_code&gt;&lt;article&gt; 值进行分组,因此需要定义一个键,它将是 &lt;description&gt;&lt;menu_code&gt; 的组合。

<xsl:key name="kArticle" match="article" use="concat(description, '|', menu_code)" />

下一步是使用键和节点 ID 对 &lt;article&gt; 节点进行分组。这将只选择适当分组的节点。

<xsl:template match="article[generate-id() = generate-id(key('kArticle', concat(description, '|', menu_code))[1])]">

其余的 &lt;article&gt; 节点将不被处理。

<xsl:template match="article" />

下面是 2 个不同的 XSLT,分别用于 XML 输出和 HTML 输出。基本的分组概念是相同的,只是改变了输出的显示方式。

XSLT - XML 输出

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

    <xsl:key name="kArticle" match="article" use="concat(description, '|', menu_code)" />

    <!-- identity transform -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="article[generate-id() = generate-id(key('kArticle', concat(description, '|', menu_code))[1])]">
        <xsl:copy>
            <xsl:apply-templates select="description" />
            <totalQty>
                <xsl:value-of select="sum(key('kArticle', concat(description, '|', menu_code))/qty)" />
            </totalQty>
            <totalAmount>
                <xsl:value-of select="format-number(sum(key('kArticle', concat(description, '|', menu_code))/amount),'#.00')" />
            </totalAmount>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="article" />
</xsl:stylesheet>

XML 输出

<articles>
    <group>
        <code>1000</code>
        <description>GROUP A</description>
        <article>
            <description>Article A</description>
            <totalQty>24</totalQty>
            <totalAmount>14.00</totalAmount>
        </article>
        <article>
            <description>Article A</description>
            <totalQty>1</totalQty>
            <totalAmount>1.00</totalAmount>
        </article>
    </group>
    <group>
        <code>2000</code>
        <description>GROUP B</description>
        <article>
            <description>Article B</description>
            <totalQty>28</totalQty>
            <totalAmount>28.00</totalAmount>
        </article>
        <article>
            <description>Article B</description>
            <totalQty>14</totalQty>
            <totalAmount>35.00</totalAmount>
        </article>
    </group>
</articles>

XSLT - HTML 输出

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

    <xsl:key name="kArticle" match="article" use="concat(description, '|', menu_code)" />

    <xsl:template match="articles">
        <html>
            <body>
                <xsl:for-each select="group">
                    <h3><xsl:value-of select="description" /></h3>
                    <table border="1" cellspacing="0" cellpadding="3">
                        <tr>
                            <th>Article Description</th>
                            <th>Total Quantity</th>
                            <th>Total Amount</th>
                        </tr>
                        <xsl:apply-templates select="article" />
                    </table>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="article[generate-id() = generate-id(key('kArticle', concat(description, '|', menu_code))[1])]">
        <tr>
            <td>
                <xsl:value-of select="description" />
            </td>
            <td>
                <xsl:value-of select="sum(key('kArticle', concat(description, '|', menu_code))/qty)" />
            </td>
            <td>
                <xsl:value-of select="format-number(sum(key('kArticle', concat(description, '|', menu_code))/amount),'#.00')" />
            </td>
        </tr>
    </xsl:template>
    <xsl:template match="article" />
</xsl:stylesheet>

HTML 输出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 2015-01-02
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    相关资源
    最近更新 更多