如何在XSLT 1.0中按Item分组并保留最新Date的条目?
XSLT分组取最新日期数据问题修复
问题分析
- 路径错误:源XML中
<Item>节点位于<E2>下,而非<E1>,但你的xsl:key中使用了E1/Item,导致无法正确匹配数据。 - 分组逻辑错误:你试图通过
concat(E1/Item,E1/Date)构建key,但每个<Level>下可能有多个<E1>(多个日期),这种方式无法正确按Item分组并筛选最新日期。 - for-each筛选逻辑错误:原表达式没有实现“按Item分组,每组取最新日期的Level”的需求。
正确XSLT实现
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 按Item值分组所有Level节点 --> <xsl:key name="item-group" match="Level" use="E2/Item"/> <xsl:template match="/"> <xsl:for-each select="Level[generate-id() = generate-id(key('item-group', E2/Item)[1])]"> <xsl:variable name="current-item" select="E2/Item"/> <!-- 对当前Item组内的Level按Date降序排序,取第一个(最新日期) --> <xsl:for-each select="key('item-group', $current-item)"> <xsl:sort select="E1/Date" order="descending"/> <xsl:if test="position() = 1"> <Level> <E1> <!-- 取当前Level下的最新Date --> <Date><xsl:value-of select="E1/Date[not(. < ../E1/Date)]"/></Date> <Item><xsl:value-of select="$current-item"/></Item> </E1> </Level> </xsl:if> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
输出结果
应用上述XSLT后,将得到预期的XML结构:
<Level> <E1> <Date>20230318</Date> <Item>001</Item> </E1> </Level> <Level> <E1> <Date>20240302</Date> <Item>002</Item> </E1> </Level>
内容的提问来源于stack exchange,提问作者Handy
相关产品推荐
相关产品推荐

