XSLT 2.0按日期分组节点问题及多Misc节点合并需求
解决XSLT处理Worker与Misc节点的归属及合并问题
需求说明
- 基于文档中所有唯一的
<Date>节点生成对应<Records>节点(共4个) - 不含
<Misc>(即无<Date>子节点)的<Worker>节点需复制到每个<Records>中
现有问题
当前使用的XSLT 2.0代码存在以下不符合预期的问题:
<Misc>节点脱离了其父<Worker>节点- 当同一
<Worker>下存在同日期但不同<BonusAmount>的多个<Misc>节点时,会生成重复的<Worker>节点
最终XSLT解决方案
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 提取所有唯一的Date值 --> <xsl:variable name="uniqueDates" select="//Date[not(.=preceding::Date)]"/> <xsl:template match="/"> <Root> <!-- 为每个唯一Date生成Records节点 --> <xsl:for-each select="$uniqueDates"> <Records> <xsl:attribute name="Date"> <xsl:value-of select="."/> </xsl:attribute> <!-- 复制无Misc的Worker节点到当前Records --> <xsl:copy-of select="//Worker[not(Misc)]"/> <!-- 处理有Misc且当前Date匹配的Worker节点 --> <xsl:for-each-group select="//Worker[Misc]" group-by="concat(@ID, '|', Date)"> <xsl:copy> <!-- 复制Worker的属性 --> <xsl:copy-of select="@*"/> <!-- 复制Worker下除Misc外的其他子节点 --> <xsl:copy-of select="*[not(self::Misc)]"/> <!-- 合并同Worker同Date的Misc节点 --> <xsl:for-each select="current-group()/Misc[Date=current()/Date]"> <xsl:copy-of select="."/> </xsl:for-each> </xsl:copy> </xsl:for-each-group> </Records> </xsl:for-each> </Root> </xsl:template> </xsl:stylesheet>
方案说明
- 提取唯一日期:通过
$uniqueDates变量获取文档中所有不重复的<Date>值,以此为基础生成对应数量的<Records>节点 - 无Misc的Worker处理:直接复制所有不含
<Misc>的<Worker>节点到每个<Records>中 - 有Misc的Worker分组合并:
- 以
Worker的ID + Date作为分组键,确保同一Worker同日期的Misc被归为一组 - 复制Worker的属性及非Misc子节点,再将同组内的所有Misc节点合并到该Worker下,既保证了Misc的归属正确性,又避免了重复生成Worker节点
- 以
内容的提问来源于stack exchange,提问作者MAT0718
相关产品推荐
相关产品推荐

