我有一个XML文件如下,我想根据发布的年份对书籍进行分组,并计算每年的书籍数量。按升序排序结果。
<body>
<outline text="A">
<outline text="Abelson, Harold" author="Harold Abelson" title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung" publisher="Springer Verlag" isbn="3540520430" year="1991"/>
<outline text="Abrahams, Paul W." author="Paul W. Abrahams" title="Tex for the Impatient" publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
</outline>
<outline text="B">
<outline text="Bach, Fred" author="Fred Bach" title="UNIX Handbuch zur Programmentwicklung" publisher="Hanser Fachbuchverlag" isbn="3446151036"/>
<outline text="Bach, Maurice J." author="Maurice J. Bach" title="Design of the UNIX Operating System" publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
</outline>
</body>
这是例外输出
<p> Group by Year </p>
<table border="1">
<tr bgcolor="yellow">
<th>Year</th>
<th>Number</th>
</tr>
<tr>
<td>1963</td>
<td>1</td>
</tr>
<tr>
<td>1966</td>
<td>1</td>
</tr>
这是我的代码:
<xsl:template match="body">
<xsl:copy>
<table border="1">
<tr bgcolor="Yellow">
<th class="cell"><span> Year </span></th>
<th class="cell"><span> Count </span></th>
</tr>
<xsl:apply-templates select="outline"/>
</table>
</xsl:copy>
</xsl:template>
<xsl:key name="groupbyyear" match="outline" use="@year"/)/>
<xsl:template match="outline/outline">
<tr>
<xsl:sort select="year" order="ascending" />
</tr>
</xsl:template>
</xsl:stylesheet>
我不确定如何使用xsl键功能,以及在键功能之后我应该在模板内做什么?
答案 0 :(得分:1)
此XSLT 1.0转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kOutlineByYear" match="outline/outline" use="@year"/>
<xsl:template match="/*">
<p> Group by Year </p>
<table border="1">
<tr bgcolor="yellow">
<th>Year</th>
<th>Number</th>
</tr>
<xsl:apply-templates select=
"outline/outline[generate-id()
=generate-id(key('kOutlineByYear',@year)[1])
]">
<xsl:sort select="@year" data-type="number"/>
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="outline/outline">
<tr>
<td><xsl:value-of select="@year"/></td>
<td><xsl:value-of select="count(key('kOutlineByYear',@year))"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(所提供的文档具有较小的更正以使其更具代表性):
<body>
<outline text="A">
<outline text="Abelson, Harold"
author="Harold Abelson"
title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung"
publisher="Springer Verlag"
isbn="3540520430" year="1991"/>
<outline text="Abrahams, Paul W." author="Paul W. Abrahams"
title="Tex for the Impatient"
publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
</outline>
<outline text="B">
<outline text="Bach, Fred" author="Fred Bach"
title="UNIX Handbuch zur Programmentwicklung"
publisher="Hanser Fachbuchverlag" isbn="3446151036" year="2000"/>
<outline text="Bach, Maurice J."
author="Maurice J. Bach"
title="Design of the UNIX Operating System"
publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
</outline>
</body>
会产生想要的正确结果:
<p> Group by Year </p>
<table border="1">
<tr bgcolor="yellow">
<th>Year</th>
<th>Number</th>
</tr>
<tr>
<td>1986</td>
<td>1</td>
</tr>
<tr>
<td>1991</td>
<td>1</td>
</tr>
<tr>
<td>2000</td>
<td>2</td>
</tr>
</table>
<强>解释强>:
正确使用 Muenchian grouping method 。
<强> II。 XSLT 2.0解决方案:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kOutlineByYear" match="outline/outline" use="@year"/>
<xsl:template match="/*">
<p> Group by Year </p>
<table border="1">
<tr bgcolor="yellow">
<th>Year</th>
<th>Number</th>
</tr>
<xsl:for-each-group select="outline/outline"
group-by="@year">
<xsl:sort select="current-grouping-key()" data-type="number"/>
<tr>
<td><xsl:value-of select="current-grouping-key()"/></td>
<td><xsl:value-of select="count(current-group())"/></td>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
当在同一个XML文档(上面)上应用此转换时,会再次生成相同的正确结果:
<p> Group by Year </p>
<table border="1">
<tr bgcolor="yellow">
<th>Year</th>
<th>Number</th>
</tr>
<tr>
<td>1986</td>
<td>1</td>
</tr>
<tr>
<td>1991</td>
<td>1</td>
</tr>
<tr>
<td>2000</td>
<td>2</td>
</tr>
</table>
<强>解释强>:
使用带有group-by
属性的XSLT 2.0指令 <xsl:for-each-group>
。
使用XSLT 2.0函数 current-group()
和 current-grouping-key()
。