MSXML6的transformNode中,XSLT/XPath Concat为何报‘Nodetest expected here’错误?
XPath concat函数在MSXML6中报错的原因与解决办法
示例XML片段
<way id="1237072661"> <nd ref="11488882051"/> <nd ref="11488882048"/> <tag k="railway" v="station"/> </way>
问题场景
在MSXML6中用transformNode执行下面的XSLT代码时,会抛出Nodetest expected here错误:
<xsl:copy-of select="*[tag[@k='railway'][@v='station']]/concat('
',name(),'/',@id)"/>
异常现象
- 移除
concat函数后,代码可正常返回有效数据 - 使用Saxon HE(支持XPath 2.0)解析时,这段带
concat的代码能正常运行
原因解析
MSXML6仅支持XPath 1.0,而你写的表达式用了XPath 2.0才允许的语法:在节点路径后直接调用函数。XPath 1.0规定,/符号后面必须是节点测试(比如元素名、*、text()这类节点相关查询),不能直接跟函数调用,这就是报错的核心原因。
Saxon HE支持XPath 2.0及更高版本,允许在路径步骤中直接调用函数,因此可以正常执行该代码。
解决办法
要在XPath 1.0中实现相同的字符串拼接效果,需要把concat放在select最外层,先定位到目标节点再调用函数:
<xsl:copy-of select="concat('
', name(*[tag[@k='railway'][@v='station']]), '/', *[tag[@k='railway'][@v='station']]/@id)"/>
如果需要处理多个匹配节点,用xsl:for-each遍历每个节点后再拼接更稳妥:
<xsl:for-each select="*[tag[@k='railway'][@v='station']]"> <xsl:value-of select="concat('
', name(), '/', @id)"/> </xsl:for-each>
内容的提问来源于stack exchange,提问作者DaveF
相关产品推荐
相关产品推荐

