我有一个数据库的XML数据转换,我希望使用xslt呈现。 对于我想要的布局,数据的结构并不“直截了当”(我还将XML数据用于另一个报告)。
我想要的是对Level-A的数据做一些计算,我需要在Level-C的孩子上进行分组。
我知道我可以再次将数据选择到一个XML文件中,其结构对于我的报告来说“简单”,但这是我的最后一招,因为我觉得它也可以在XSLT中完成。最值得探讨的是,我需要一些“Muenchian”技巧才能完成它,但由于我是一个'Muenchian Virgin',我会在每次尝试中陷入困境(我试图'偷'并改变......)。
有人知道Muenchian是否可以继续进行,有人可以帮助我走上正轨吗? 我做了一些阅读(包括Jeni Tennison的),但到目前为止我看到的东西并没有涵盖我的问题,据我所知......
下面是一个简化的XML结构,它(或多或少)代表我的真实问题。
有什么想法吗?
亲切的问候,Henk
<data>
<a>
<a_id>A1</a_id>
<a_desc>A one</a_desc>
<a_val>1</a_val>
<b>
<c>
<c_id>C2</c_id>
<c_desc>C two</c_desc>
</c>
</b>
</a>
<a>
<a_id>A2</a_id>
<a_desc>A two</a_desc>
<a_val>2</a_val>
<b>
<c>
<c_id>C2</c_id>
<c_desc>C two</c_desc>
</c>
</b>
</a>
<a>
<a_id>A3</a_id>
<a_desc>A three</a_desc>
<a_val>3</a_val>
<b>
<c>
<c_id>C1</c_id>
<c_desc>C one</c_desc>
</c>
</b>
</a>
<a>
<a_id>A4</a_id>
<a_desc>A four</a_desc>
<a_val>7</a_val>
<b>
<c>
<c_id>C3</c_id>
<c_desc>C three</c_desc>
</c>
</b>
</a>
<a>
<a_id>A5</a_id>
<a_desc>A five</a_desc>
<a_val>11</a_val>
<b>
<c>
<c_id>C1</c_id>
<c_desc>C one</c_desc>
</c>
</b>
</a>
</data>
C_desc Count() Sum(a_val) Avg(a_val)
------ ------- ---------- ----------
C one 3 15 5
C two 1 2 2
C three 1 7 7
答案 0 :(得分:1)
正如您所提到的,Muenchian分组是可行的方法(在XSLT1.0中)。您说要使用 c 元素中的值对 a 元素进行分组。因此,您可以像这样定义一个键:
<xsl:key name="a" match="a" use="b/c/c_desc" />
然后,您需要获得'distinct' a 元素,这是通过选择恰好是给定键的组中第一个元素的 a 元素来完成的。你用这个相当可怕的表达式
来做到这一点<xsl:apply-templates
select="//a[generate-id() = generate-id(key('a', b/c/c_desc)[1])]" />
在这里,key('a', b/c/c_desc)[1]
会找到键组中的第一个元素,然后使用generate-id
来比较元素。
然后,您将拥有一个模板来匹配不同的 a 元素,然后您可以在其中对该组进行计算。例如,要获得总和:
<xsl:value-of select="sum(key('a', b/c/c_desc)/a_val)" />
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="exsl">
<xsl:output method="html" indent="yes"/>
<xsl:key name="a" match="a" use="b/c/c_desc" />
<xsl:template match="/">
<table>
<tr>
<td>C_desc</td>
<td>Count</td>
<td>Sum</td>
<td>Avg</td>
</tr>
<xsl:apply-templates select="//a[generate-id() = generate-id(key('a', b/c/c_desc)[1])]" />
</table>
</xsl:template>
<xsl:template match="a">
<xsl:variable name="c_desc" select="b/c/c_desc" />
<tr>
<td><xsl:value-of select="count(key('a', $c_desc))" /></td>
<td><xsl:value-of select="sum(key('a', $c_desc)/a_val)" /></td>
<td><xsl:value-of select="sum(key('a', $c_desc)/a_val) div count(key('a', $c_desc))" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<table>
<tr>
<td>C_desc</td>
<td>Count</td>
<td>Sum</td>
<td>Avg</td>
</tr>
<tr>
<td>3</td>
<td>15</td>
<td>5</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>1</td>
<td>7</td>
<td>7</td>
</tr>
</table>