在 XSLT 1.0 中,可以通过称为Muenchian Grouping 的技术来实现分组。
在您的示例中,由于要根据 <description> 和 <menu_code> 对 <article> 值进行分组,因此需要定义一个键,它将是 <description> 和 <menu_code> 的组合。
<xsl:key name="kArticle" match="article" use="concat(description, '|', menu_code)" />
下一步是使用键和节点 ID 对 <article> 节点进行分组。这将只选择适当分组的节点。
<xsl:template match="article[generate-id() = generate-id(key('kArticle', concat(description, '|', menu_code))[1])]">
其余的 <article> 节点将不被处理。
<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 输出