使用XSLT Muenchian方法提取节点属性值并去重的问题
解决XSLT中按Product节点独立获取去重@value属性的问题
嘿,我来帮你搞定这个需求!首先得指出你现有代码里的几个关键问题,然后给你一个能实现目标的可行方案:
需求回顾
你需要针对每个独立的<Product>节点,获取它祖先、自身及所有后代节点的@value属性值,去重后输出成指定的<values>标签格式,而且不能用//选择器,必须基于Product节点的轴来处理。
现有代码的问题
- Key匹配对象错误:你定义的
<xsl:key>匹配的是value元素,但我们要处理的是@value属性,二者完全不匹配; - 无效的
sortedvalues节点:你的代码里用到了sortedvalues,但你的XML中根本不存在这个节点,导致key的索引和排序条件全部失效; - 未针对单个Product独立处理:当前逻辑没有绑定到每个Product的上下文,会导致全局去重,不符合你要每个Product输出自身去重值的需求。
另外,你的原始XML存在标签未闭合的问题,我先帮你修正为可正常解析的版本:
<Root> <something value="asd"></something> <something value="dsa"></something> <Product> <something value="asd"></something> <something value="dsa"></something> <something value="asd"></something> <anothernode> <something value="qwe"></something> </anothernode> <anothernode2> <something value="ewq"></something> </anothernode2> <something value="ewq"></something> </Product> <Product> <something value="asd"></something> <something value="dsa"></something> <something value="asd"></something> <anothernode> <something value="qwe"></something> </anothernode> <anothernode2> <something value="ewq"></something> </anothernode2> <something value="ewq"></something> </Product> </Root>
可行的XSLT解决方案
下面的代码完全符合你的要求,每个Product节点独立处理,基于轴获取属性并去重:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 为当前Product上下文的@value属性创建key,按属性值分组 --> <xsl:key name="unique-values" match="ancestor-or-self::*/@value | descendant-or-self::*/@value" use="." /> <!-- 从根节点开始,只处理每个Product节点 --> <xsl:template match="/Root"> <xsl:apply-templates select="Product"/> </xsl:template> <!-- 处理单个Product节点 --> <xsl:template match="Product"> <Product> <!-- 筛选当前Product下的唯一@value值:只保留每组的第一个元素 --> <xsl:for-each select="(ancestor-or-self::*/@value | descendant-or-self::*/@value)[generate-id() = generate-id(key('unique-values', .)[1])]"> <!-- 按属性值排序,让输出更整洁 --> <xsl:sort select="."/> <values><xsl:value-of select="."/></values> </xsl:for-each> </Product> </xsl:template> <!-- 忽略空白文本节点,避免输出多余内容 --> <xsl:template match="text()"/> </xsl:stylesheet>
代码说明
- Key的作用:
unique-valueskey会把当前Product上下文里所有符合条件的@value属性按值分组,相同值会被归为一组; - Product节点处理:对每个Product,先输出
<Product>标签,再通过generate-id()判断是否是每组的第一个元素,从而实现去重; - 排序优化:加入
<xsl:sort>让输出的<values>按字母顺序排列,和你期望的输出一致; - 清理输出:最后一个模板用来忽略XML里的空白文本,避免输出多余的换行或空格。
用这个代码处理修正后的XML,就能得到你想要的输出:
<Product> <values>asd</values> <values>dsa</values> <values>ewq</values> <values>qwe</values> </Product> <Product> <values>asd</values> <values>dsa</values> <values>ewq</values> <values>qwe</values> </Product>
内容的提问来源于stack exchange,提问作者alan samuel
相关产品推荐
相关产品推荐

