问题描述
我有这个源xml:
<cip>
<data>
<typo>
<articles>
<article id="BM017106--">
<lang>Lang Text(de-AT) -- BM017106--:6</lang>
</article>
<article id="XC01010101">
<lang>H07V-U (Ye) 1,5mm² schwarz,PVC Aderleitung eindrähtig</lang>
</article>
</articles>
</typo>
</data>
</cip>
以及以下 xslt:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:message select="cip/data/typo/articles/article[1]/@id"/>
</xsl:template>
</xsl:stylesheet>
当我用 Saxon saxon9ee.jar 转换它时,一切正常。 当我尝试使用 saxon-ee-10.3.jar 转换它时,我得到:错误 XTDE0420,无法创建其父节点是文档节点的属性节点 (id)。 有人知道出了什么问题吗?
解决方法
XSLT 3.0 规范说(在 §23.1 中):
如果 xsl:message 指令包含一个序列构造函数,那么 使用通过评估此序列构造函数获得的序列 构造新文档节点的内容,如 5.7.1 构建复杂内容。
并且 5.7.1 表示尝试将属性节点附加到文档节点是错误的。
§23.1 继续说:
计算选择表达式时发生的任何动态错误 或包含的序列构造函数,以及任何序列化错误 处理结果时发生的,不会导致 转型失败;在最坏的情况下,这意味着没有消息输出, 或者输出的唯一消息是与 发生的错误。
这就是 Saxon 所做的:它将错误消息作为 xsl:message
指令的内容输出,然后转换继续进行。
紧随其后的注释描述了这种情况,其中 xsl:message
试图输出一个属性节点。但是该注释不正确地指出是否向用户发出信号以及它们是否导致转换终止是实现定义的 -- 规范文本清楚地表明错误永远不会致命.
因此 Saxon 的行为方式与规范一致,尽管可以说可以做得更好,例如通过使用自适应序列化方法序列化传递给 xsl:message
的值。
我不确定为什么它会在不同版本之间发生变化。