XPTY0020错误排查:统计同眼色人数的XSLT代码问题
解决XSLT的XPTY0020错误及眼睛颜色人数统计问题
错误原因
你遇到的XPTY0020错误,是因为xsl:for-each的select用了distinct-values(),返回的是**原子类型值(比如xs:string)**而非节点。此时上下文项.是原子值,当你写Person[@id=...]这种相对路径时,XSLT会尝试在原子值的上下文里查找子节点,违反了子轴必须以node()作为上下文项的规则,因此报错。
修复方案
方案1:改用节点分组(推荐,更高效)
用xsl:for-each-group对Eye_colour节点按Colour分组,上下文始终是节点,不会出现类型问题,同时直接统计每组对应的人数:
<li class="list-group-item">Total of people with <xsl:value-of select="key('Eye_colour-by-id',id)/Colour"/>-coloured eyes: <xsl:for-each-group select="/Data/Eye_colours/Eye_colour" group-by="Colour"> <xsl:value-of select="concat(current-grouping-key(), ': ')"/> <!-- 统计当前分组下所有Eye_colour对应的Person数量 --> <xsl:value-of select="count(/Data/Persons/Person[@id = current-group()/Ref_id])"/> <xsl:text>
</xsl:text> </xsl:for-each-group> </li>
方案2:保留distinct-values但使用绝对路径
如果坚持用distinct-values,需要把Person的查找改为绝对路径,避免在原子值上下文里使用相对路径:
<li class="list-group-item">Total of people with <xsl:value-of select="key('Eye_colour-by-id',id)/Colour"/>-coloured eyes: <xsl:for-each select="distinct-values(/Data/Eye_colours/Eye_colour/Colour)"> <xsl:value-of select="concat(., ': ')"/> <!-- 用绝对路径/Data/Persons/Person代替相对路径Person --> <xsl:value-of select="count(/Data/Persons/Person[@id=/Data/Eye_colours/Eye_colour[Colour=current()]/Ref_id])"/> <xsl:text>
</xsl:text> </xsl:for-each> </li>
补充说明
- 方案1使用分组更符合XSLT的设计思想,性能也更好,尤其是数据量较大时。
- 确保你的XSLT处理器支持XSLT 2.0及以上版本(
xsl:for-each-group是2.0新增特性),如果只能用1.0,可以用Muenchian分组替代。
内容的提问来源于stack exchange,提问作者unknowncover
相关产品推荐
相关产品推荐

