我正在执行 XSLT 转换以创建<button>
具有onclick
属性的 HTML 元素。当我在按钮的文本内容之前定义onclick
属性时,一切都按预期工作。以下是有效的代码:
<xsl:element name="button">
<xsl:attribute name="onclick">
console.log(600);
</xsl:attribute>
<xsl:text>Click Me</xsl:text>
</xsl:element>
输出:
<button onclick="console.log(600);">Click Me</button>
但是,如果我将其放在内容xsl:attribute
后面xsl:text
,如下所示:
<xsl:element name="button">
<xsl:text>Click Me</xsl:text>
<xsl:attribute name="onclick">
console.log(600);
</xsl:attribute>
</xsl:element>
该属性被忽略,输出仅包含文本:
<button>Click Me</button>
为什么放置xsl:attribute
在后面会xsl:text
导致属性消失?XSLT 中是否有规则要求在内容之前定义属性,如果是,背后的原因是什么?为什么会这样?
规则位于https://www.w3.org/TR/xslt-10/#creating-attributes:
所以是的,您需要在任何子节点(如文本节点)之前输出属性,否则您可能会收到错误或您的 XSLT 处理器会忽略该属性。
回答补充问题:
原因是 XSLT 处理器可以并且经常会将输出直接写入序列化输出流,从而绕过结果树的构造。并且(尽管规范没有强制要求)它们通常按照写入的顺序从上到下执行指令。因此,该语言的设计目的是使按顺序执行指令的处理器能够轻松地按顺序创建输出。
XSLT 1.0 规范相当自由地使用时间语言:“在元素中添加子元素后再向其添加属性”。后续版本试图避免这种情况。在 XSLT 2.0 中,规则变为:
还要注意,XSLT 2.0 要求处理器抛出错误,忽略属性的选项已经消失。XSLT 2.0 试图 (a) 使处理器更具互操作性,以及 (b) 要求报告更多用户错误,而不是导致后备操作。