如何通过子元素remarks属性值筛选XML父元素(XSLT实现)
解决XSLT无法遍历所有Marker元素筛选item的问题
问题
需要筛选出所有包含**子元素Marker且其remarks属性含"blue"(不区分大小写)**的item父元素,但现有XSLT仅匹配第一个Marker元素的属性,无法遍历所有子元素。
示例代码与输出
XML输入
<root> <item> <Marker remarks="Red marker"/> <Marker remarks="Blue pen"/> </item> <item> <Marker remarks="Green eraser"/> </item> <item> <Marker remarks="light blue notebook"/> <Marker remarks="Yellow highlighter"/> </item> </root>
原XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <root> <xsl:copy-of select="root/item[Marker/@remarks[contains(translate(., 'BLUE', 'blue'), 'blue')]]"/> </root> </xsl:template> </xsl:stylesheet>
当前错误输出
<root> <item> <Marker remarks="light blue notebook"/> <Marker remarks="Yellow highlighter"/> </item> </root>
期望正确输出
<root> <item> <Marker remarks="Red marker"/> <Marker remarks="Blue pen"/> </item> <item> <Marker remarks="light blue notebook"/> <Marker remarks="Yellow highlighter"/> </item> </root>
修正后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <root> <xsl:copy-of select="root/item[Marker[contains(translate(@remarks, 'BLUE', 'blue'), 'blue')]]"/> </root> </xsl:template> </xsl:stylesheet>
核心修改点解释
- 原代码中
Marker/@remarks[contains(...)]的逻辑是:先取当前item下第一个Marker的remarks属性,再判断是否匹配,这就导致只检查第一个子元素,忽略了后续的Marker。 - 修改为
Marker[contains(translate(@remarks, 'BLUE', 'blue'), 'blue')]后,会遍历item下所有Marker子元素,只要其中任意一个的remarks属性(转小写后)包含"blue",就会选中该item。 translate函数用于统一大小写,确保匹配不区分大小写(不管是"Blue"、"BLUE"还是"blue"都能被识别)。
内容的提问来源于stack exchange,提问作者gyuszmok
相关产品推荐
相关产品推荐

