当运行以下输入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>
请通过解释
root
的xsl: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/