XSLT转换XML时依赖数据重复问题求解
解决XSLT转换中重复依赖节点的问题
核心思路:精准分组/去重
你的问题本质是同一worker下重复的<wd:GPAR_LRV_Dependents_group>节点未被正确去重,之前的for-each-group没生效大概率是分组上下文或分组键选得不对,以下是具体可行方案:
方案1:XSLT 2.0+ 正确使用for-each-group
确保在worker节点的上下文中,按依赖的唯一标识(比如依赖ID字段,假设是wd:Dependent_ID)分组:
<!-- 先定位到当前worker节点 --> <xsl:for-each select="wd:worker"> <!-- 对当前worker下的重复依赖节点按ID分组 --> <xsl:for-each-group select="wd:GPAR_LRV_Dependents_group" group-by="wd:Dependent_ID"> <!-- 输出分组后的唯一依赖数据 --> <依赖信息> <依赖ID><xsl:value-of select="current-grouping-key()"/></依赖ID> <其他字段><xsl:value-of select="wd:Other_Field"/></其他字段> </依赖信息> </xsl:for-each-group> </xsl:for-each>
注意:如果依赖ID不是直接在<wd:GPAR_LRV_Dependents_group>下,要调整group-by的路径,确保指向唯一标识字段。
方案2:XSLT 1.0 用key()去重
如果只能用XSLT 1.0,先定义键,再筛选每个依赖的第一个实例:
<!-- 定义键:按worker和依赖ID唯一标识 --> <xsl:key name="uniqueDependent" match="wd:GPAR_LRV_Dependents_group" use="concat(../../wd:Worker_ID, '|', wd:Dependent_ID)"/> <!-- 输出唯一依赖 --> <xsl:for-each select="wd:worker/wd:GPAR_LRV_Dependents_group[generate-id() = generate-id(key('uniqueDependent', concat(../../wd:Worker_ID, '|', wd:Dependent_ID))[1])]"> <依赖信息> <依赖ID><xsl:value-of select="wd:Dependent_ID"/></依赖ID> <!-- 其他字段输出 --> </依赖信息> </xsl:for-each>
这里用concat(Worker_ID, '|', Dependent_ID)作为键,避免不同worker的同ID依赖被误去重。
方案3:通过计算字段(位置判断)实现
如果没有唯一ID,可通过判断是否是当前worker下该依赖的第一个出现实例来过滤,但这种方式仅适用于重复节点内容完全一致的场景:
<xsl:for-each select="wd:worker"> <xsl:variable name="currentWorker" select="."/> <xsl:for-each select="wd:GPAR_LRV_Dependents_group"> <!-- 只输出当前worker下该节点的第一个实例 --> <xsl:if test="position() = 1 or not(. = $currentWorker/wd:GPAR_LRV_Dependents_group[position() < current()/position()])"> <依赖信息> <!-- 字段输出 --> </依赖信息> </xsl:if> </xsl:for-each> </xsl:for-each>
但这种方式效率较低,优先推荐用唯一ID分组的方案。
排查之前失败的原因
- 用
for-each-group时,可能是在全局上下文而非worker上下文分组,导致跨worker的依赖被错误合并; position()方法如果没结合worker上下文,只会按整个节点列表的位置判断,而非当前worker下的相对位置。
内容的提问来源于stack exchange,提问作者Fariya
相关产品推荐
相关产品推荐

