求助:如何通过XSLT删除identifier与response中value元素空格前ID匹配的<Text>标签值
正确实现匹配ID后删除对应标签内容的XSLT方案
你的问题出在嵌套的<xsl:for-each>循环上:每遍历一个<value>元素,就会重新遍历所有的<Text>元素,这就导致符合保留条件的<Text>会被重复输出(例子里有2个<value>,所以每个要保留的文本会被输出2次)。而且你的输出结构也没有正确包裹成单一的<text>容器,而是每个匹配项都生成了独立的<text>标签。
下面是修正后的XSLT方案,能精准实现你的需求:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 全局变量:收集所有需要排除的Text identifier(从value中提取空格前的ID) --> <xsl:variable name="exclude-ids"> <xsl:for-each select="//response/option/value"> <id><xsl:value-of select="substring-before(., ' ')"/></id> </xsl:for-each> </xsl:variable> <!-- 将变量转换为节点集,方便后续筛选(XSLT 1.0需要用node-set()函数,不同处理器可能需要对应命名空间) --> <xsl:variable name="exclude-id-set" select="exsl:node-set($exclude-ids)/id" xmlns:exsl="http://exslt.org/common"/> <xsl:template match="/"> <text> <!-- 筛选出identifier不在排除列表中的Text元素 --> <xsl:for-each select="//Text[not(@identifier = $exclude-id-set)]"> <txt> <xsl:value-of select="."/> </txt> </xsl:for-each> </text> </xsl:template> </xsl:stylesheet>
关键说明:
- 全局变量收集排除ID:先把所有
<value>元素中空格前的ID提取出来,存入变量,避免重复遍历。 - 节点集转换:XSLT 1.0中,变量默认是结果树片段,需要用
node-set()函数转换成可查询的节点集(如果使用XSLT 2.0及以上,这一步可以省略,直接用序列处理)。 - 单一循环筛选:只遍历一次
<Text>元素,通过not(@identifier = $exclude-id-set)判断是否需要保留,避免重复输出。 - 正确的输出结构:所有保留的
<txt>标签都包裹在一个<text>容器内,符合你的预期输出格式。
测试结果:
用你提供的输入XML运行上述XSLT,会得到完全符合预期的输出:
<text> <txt>spring</txt> <txt>summer</txt> </text>
如果你的XSLT处理器不支持EXSLT的node-set(),可以改用处理器自带的扩展(比如MSXML的msxsl:node-set),或者升级到XSLT 2.0/3.0来简化处理。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

