XPath1.0无法使用preceding-sibling时按属性变化过滤节点集方案
问题原因说明
原代码的核心问题是
preceding-sibling::car[1]匹配的是原始文档树中当前节点的前一个同级car节点,而非你提前筛选出的黄色car节点集内的前一个节点,因此会被非黄色car节点干扰,导致匹配失效。
解决方案
方案1:XPath 2.0+ 单表达式实现(无需修改代码结构)
如果运行环境支持XPath 2.0及以上版本,直接替换apply-templates的select属性即可,全程只操作筛选后的黄色car节点集,不受原始文档结构影响:
<xsl:template match="/"> <xsl:variable name="yellowCars" select="/cars/car[@color = 'yellow']"/> <changedinspectiondate> <xsl:apply-templates select="for $idx in 1 to count($yellowCars) return $yellowCars[$idx > 1 and not(@inspectiondate = $yellowCars[$idx - 1]/@inspectiondate)]"/> </changedinspectiondate> </xsl:template>
方案2:XSLT 1.0 兼容最简实现
如果仅能使用XSLT 1.0,通过遍历筛选后的节点集比对位置即可,逻辑更易读:
<xsl:template match="/"> <xsl:variable name="yellowCars" select="/cars/car[@color = 'yellow']"/> <changedinspectiondate> <xsl:for-each select="$yellowCars"> <xsl:variable name="curPos" select="position()"/> <xsl:if test="$curPos > 1 and not(@inspectiondate = $yellowCars[$curPos - 1]/@inspectiondate)"> <xsl:apply-templates select="."/> </xsl:if> </xsl:for-each> </changedinspectiondate> </xsl:template>
这里的position()返回的是节点在$yellowCars筛选集内的位置,和原始文档的节点顺序无关,完全规避了非黄色节点的干扰。
内容的提问来源于stack exchange,提问作者woodduck
相关产品推荐
相关产品推荐

