如何用Muenchian分组算法通过XSLT去重XML记录并保留含子节点的记录
XSLT使用Muenchian分组去重优先保留带子节点记录的调整方案
问题根源
原有实现默认保留分组内第一个出现的节点,没有针对是否带子节点做优先级排序,所以无法命中需要保留的目标记录。
调整方案
调整分组逻辑,优先提取同id分组内带子节点的assignment节点,仅当分组内无带子节点的记录时才保留第一个普通节点。
调整后核心代码
<!-- 按assigmentId的id属性对assignment节点分组 --> <xsl:key name="assignmentById" match="ns0:assignment" use="ns0:assigmentId/@id"/> <!-- 匹配非最优节点直接删除:最优节点为同分组内第一个带子节点的assignment,无则取分组第一个节点 --> <xsl:template match="/ns0:students/ns0:assignment[ not( generate-id() = generate-id( (key('assignmentById', ns0:assigmentId/@id)[ns0:assigmentId/*])[1] | (key('assignmentById', ns0:assigmentId/@id)[not(ns0:assigmentId/*)])[1] ) ) ]"/>
注意事项
- 你提供的输入示例中第一个
assigmentId的属性为大写Id,其余为小写id,如果真实数据存在大小写混用的情况,可将key的use属性修改为use="ns0:assigmentId/@*[lower-case(local-name())='id']"做兼容(XSLT 2.0及以上支持lower-case函数,1.0可改用translate实现大小写转换)。 - 需确保
ns0命名空间在xsl:stylesheet根节点中声明的URI与输入XML完全一致,否则会出现匹配失效的问题。 - 针对你给出的输入示例,调整后的代码会正确保留包含
ns0:assignmentDetails子节点的assignment记录,删除另外两条同id的空记录。
内容的提问来源于stack exchange,提问作者Ibrahim Schi
相关产品推荐
相关产品推荐

