xslt - XSLT模板的歧义澄清

标签 xslt xpath xslt-1.0 xslt-2.0

当运行以下输入XML

<root>
    <value>false</value>
    <value>true</value>
</root>

针对以下XSLT:
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="value">
    <true_value/>
</xsl:template>

<xsl:template match="value[. = 'false']">
    <false_value/>
</xsl:template>

</xsl:stylesheet>

我收到带有'false'的value元素,因为其内容更改为false_value ..,而所有其他value元素都变成了true_value
输出:
<?xml version="1.0" encoding="utf-8"?>
<root>
   <false_value/>
   <true_value/>
</root>

但是只有当我将模板匹配更改为root/value时,我才会得到模棱两可的模板警告。
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="root/value">
    <true_value/>
</xsl:template>

<xsl:template match="root/value[. = 'false']">
    <false_value/>
</xsl:template>

</xsl:stylesheet>

请通过解释rootxsl:template的xpath中添加@match有什么区别,使我得到此警告来帮助我。(Ambiguous rule match for /root[1]/value[1])

最佳答案

您的结果归因于隐式模板优先级。您可以在任何模板上明确指定优先级:

<xsl:template match="foo" priority="2"/>

但是在大多数情况下,您没有明确说明希望模板采用的优先级-这是默认优先级介入的地方。如果模板之间存在冲突,即,如果输入节点与多个模板匹配,则为XSLT定义使用默认优先级的冲突解决过程。

导致处理器发出警告的两个模板:
<xsl:template match="root/value">


<xsl:template match="root/value[. = 'false']">

具有相同的默认优先级(0.5)。您可能会认为匹配模式match="root/value[. = 'false']"match="root/value"更具体,但是就规范而言,并不是这样-它们具有完全相同的优先级。

这就是为什么报告了不明确的规则匹配的原因。模棱两可的规则匹配是无法通过显式或隐式优先级解决冲突的情况。作为最后的选择,选择最后一个模板

要完成此思想实验,请将模板的顺序更改为
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="root/value[. = 'false']">
    <false_value/>
</xsl:template>

<xsl:template match="root/value">
    <true_value/>
</xsl:template>

</xsl:stylesheet>

结果将是(在线here上查看):
<?xml version="1.0" encoding="utf-8"?>
<root>
   <true_value/>
   <true_value/>
</root>

如您所见,对于这两个value元素,都选择了最后一个模板。

然后,为什么将root/添加到模板匹配项会导致有关模板歧义性的警告?

您所做的特定更改来自
<xsl:template match="value">


<xsl:template match="root/value">

这将更改模板的默认优先级(如上所述)。 value的默认优先级为0,root/value的默认优先级为0.5。仅在第二种情况下才会发生冲突,因为另一个模板的默认优先级也为0.5。

root/添加到第二个模板:
<xsl:template match="root/value[. = 'false']">

不更改任何内容,默认优先级保持为0.5。

参见relevant part of the XSLT specification。注意:默认优先级并非一目了然。

所有优先事项:
<xsl:template match="value">                        0
<xsl:template match="value[. = 'false']">         0.5
<xsl:template match="root/value">                 0.5
<xsl:template match="root/value[. = 'false']">    0.5

关于xslt - XSLT模板的歧义澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27079340/

相关文章:

html - 如何使用 XSL 创建 HTML 属性?

XSLT:copy-of 如何修改内容来替换某些元素?

python - 无法在 Python 中找到 Selenium Webdriver 路径的元素

xpath - wso2 ESB中的字符串填充是否有任何XPath表达式?

json - 使用 XSLT 1.0 版从 JSON 文件中提取信息

XML/XSL 用 <br/> 替换空格

c++ - libxml2 xpath 解析,无法按预期工作

xml - 如何检查xml列表中的两个代码?

java - 如何在XSL中添加空格?

xml - XSLT:基于 2 个子元素的元素的数学加法