如何使用xsl:key实现跨分组查找重复bag编号,支持分组参数化
实现结论
完全可以使用xsl:key实现该需求,相比原有实现性能更好,且天然支持参数化指定目标分组,无需为不同分组重复编写同类逻辑。
实现思路
- 定义全局
xsl:key按bagn的文本值索引所有bagn节点,可快速查询某个值是否在文档中存在对应节点 - 将目标分组名设置为入参,动态筛选目标分组下的
bagn节点,判断时排除目标分组自身的节点即可
完整XSLT实现(兼容XSLT 1.0/2.0+)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 全局key:按bagn值索引所有bagn节点 --> <xsl:key name="bagnByValue" match="bagn" use="."/> <!-- 目标分组参数,可外部传值,支持g/h/i等任意分组名 --> <xsl:param name="targetGroup" select="'g'"/> <xsl:template match="/"> <xsl:variable name="duplicateBags"> <!-- 筛选目标分组下、在其他分组也存在的bagn --> <xsl:for-each select="/root/*[name()=$targetGroup]/bagn[key('bagnByValue', .)[../name() != $targetGroup]]"> <xsl:choose> <xsl:when test="position()=1"> <xsl:value-of select="concat('|', ., '|')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="concat(., '|')"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:variable> <xsl:value-of select="$duplicateBags"/> </xsl:template> </xsl:stylesheet>
效果验证
- 传入参数
targetGroup='g'时输出结果:|A|B|,和原有实现完全一致 - 传入参数
targetGroup='h'时输出结果:|A| - 传入参数
targetGroup='i'时输出结果:|B|
方案优势
- 全参数化:仅需修改
targetGroup参数值即可查询任意分组的跨组重复bag编号,无需重复编写逻辑 - 性能更优:
xsl:key会预构建索引,在XML数据量较大时,查询性能远高于原有逐值对比的实现方式
内容的提问来源于stack exchange,提问作者Guasqueño
相关产品推荐
相关产品推荐

