Lin*_* CS 6 xslt xpath xslt-2.0 xslt-1.0
运行以下输入XML时
<root>
<value>false</value>
<value>true</value>
</root>
Run Code Online (Sandbox Code Playgroud)
针对以下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>
Run Code Online (Sandbox Code Playgroud)
我的value元素带有'false',因为它的内容改为false_value..而且所有其他value元素都变成了true_value.输出:
<?xml version="1.0" encoding="utf-8"?>
<root>
<false_value/>
<true_value/>
</root>
Run Code Online (Sandbox Code Playgroud)
但是只有当我更改模板匹配时才会出现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>
Run Code Online (Sandbox Code Playgroud)
请帮助我解释root在xsl:template's 中添加xpath @match使得我得到这个警告的区别.(Ambiguous rule match for /root[1]/value[1])
Mat*_*ler 11
您的结果是由于隐式模板优先级.您可以在任何模板上明确指定优先级:
<xsl:template match="foo" priority="2"/>
Run Code Online (Sandbox Code Playgroud)
但在大多数情况下,您没有明确说明您希望模板采用哪种优先级 - 这就是默认优先级的步骤.如果模板之间存在冲突,即,如果输入节点与多个模板匹配,则XSLT定义利用默认优先级的冲突解决程序.
导致处理器发出警告的两个模板:
<xsl:template match="root/value">
Run Code Online (Sandbox Code Playgroud)
和
<xsl:template match="root/value[. = 'false']">
Run Code Online (Sandbox Code Playgroud)
具有相同的默认优先级(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>
Run Code Online (Sandbox Code Playgroud)
结果将是(在线查看):
<?xml version="1.0" encoding="utf-8"?>
<root>
<true_value/>
<true_value/>
</root>
Run Code Online (Sandbox Code Playgroud)
如您所见,对于这两个value元素,选择最后一个模板.
那么,为什么root/在模板模糊度警告中添加模板匹配结果呢?
您所做的具体更改来自
<xsl:template match="value">
Run Code Online (Sandbox Code Playgroud)
至
<xsl:template match="root/value">
Run Code Online (Sandbox Code Playgroud)
这会更改模板的默认优先级(如上所述).默认优先级value为0,默认优先级root/value为0.5.只有在第二种情况下才会出现冲突,因为另一个模板的默认优先级也是0.5.
添加root/到第二个模板:
<xsl:template match="root/value[. = 'false']">
Run Code Online (Sandbox Code Playgroud)
不会更改任何内容,默认优先级保持为0.5.
请参阅XSLT规范的相关部分.警告:默认优先级并不容易阅读.
所有重点:
<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
Run Code Online (Sandbox Code Playgroud)