英文:
Grouping & counting by two XML elements with XSLT
问题
以下是您要求的XSLT代码,以实现按姓氏和年龄进行分组和计数:
<xsl:key name="custs-by-lastname-age" match="cust" use="concat(lastname, '|', age)"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
<th>#</th>
</tr>
<xsl:for-each select="/root/cust[count(. | key('custs-by-lastname-age', concat(lastname, '|', age))[1]) = 1]">
<xsl:sort select="lastname"/>
<tr>
<td>
<xsl:value-of select="lastname"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
<td>
<xsl:value-of select="count(key('custs-by-lastname-age', concat(lastname, '|', age)))"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
这将按照姓氏和年龄进行分组和计数,以实现您所期望的输出。
英文:
This is my input XML:
<root>
<cust>
<firstname>bob</firstname>
<lastname>smith</lastname>
<age>40</age>
</cust>
<cust>
<firstname>joe</firstname>
<lastname>smith</lastname>
<age>75</age>
</cust>
<cust>
<firstname>joe</firstname>
<lastname>brown</lastname>
<age>25</age>
</cust>
<cust>
<firstname>pete</firstname>
<lastname>smith</lastname>
<age>40</age>
</cust>
</root>
Runnning it through the following XSLT:
<xsl:key name="custs-by-lastname" match="cust" use="lastname"/>
<xsl:template match="/">
<html><body>
<table border="1">
<tr><th>Name</th><th>#</th></tr>
<xsl:for-each select="/root/cust[count(. | key('custs-by-lastname', lastname)[1]) = 1]">
<xsl:sort select="lastname"/>
<tr>
<td><xsl:value-of select="lastname"/></td>
<td><xsl:value-of select="count(key('custs-by-lastname', lastname))"/></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
will result in this output:
Name #
brown 1
smith 3
So what the XSLT does is grouping by lastname and counting.
What I would like to achieve is this output (order unimportant):
Name Age #
smith 40 2
brown 25 1
smith 75 1
so grouping by lastname AND age.
I've tried to fiddle with combining lastname and age in the key-function, but I was unable to come up with a solution.
答案1
得分: 2
如果你想按姓名和年龄进行分组,那么请使用姓名和年龄的连接作为键值:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="cust" match="cust" use="concat(lastname, age)"/>
<xsl:template match="/root">
<html>
<body>
<table border="1">
<tr>
<th>姓名</th>
<th>年龄</th>
<th>#</th>
</tr>
<xsl:for-each select="cust[count(. | key('cust', concat(lastname, age))[1]) = 1]">
<xsl:sort select="lastname"/>
<tr>
<td>
<xsl:value-of select="lastname"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
<td>
<xsl:value-of select="count(key('cust', concat(lastname, age)))"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
请注意,这假设没有以数字结尾的姓名。通常,连接的键值会包含一个分隔符(例如 concat(lastname, '|', age)
)以防止误匹配。
英文:
If you want to group by name and age, then use the concatenation of name and age as the key value:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="cust" match="cust" use="concat(lastname, age)"/>
<xsl:template match="/root">
<html>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Age</th>
<th>#</th>
</tr>
<xsl:for-each select="cust[count(. | key('cust', concat(lastname, age))[1]) = 1]">
<xsl:sort select="lastname"/>
<tr>
<td>
<xsl:value-of select="lastname"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
<td>
<xsl:value-of select="count(key('cust', concat(lastname, age)))"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Note that this assumes that no name ends with a digit. Usually, a concatenated key value will include a separator (e.g. concat(lastname, '|', age)
to prevent false matches.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论