这种模棱两可的规则不应该发生吗?

时间:2014-01-21 13:58:44

标签: xslt xslt-2.0 operator-precedence

试图理解next-match我在xmlplease.com找到了一个例子,但是当我自己尝试一下时,我得到一个Ambiguous rule match for ...,我真的看不出它是怎样的不会通过这个例子得到它。如何将第三个模板优先于其他两个?

示例是错误的,还是我在这里遗漏了什么?


XSLT

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="yes" />
    <xsl:template match="/">
        <PRODUCTS>
            <xsl:apply-templates />
        </PRODUCTS>
    </xsl:template>
    <xsl:template match="product">
        <PRODUCT id="{@id}" price="{@price}" stock="{@stock}" />
    </xsl:template>
    <xsl:template match="product[@id = 'p2']">
        <PRODUCT id="{@id}" price="{@price * 1.25}" stock="{@stock}" />
    </xsl:template>
    <xsl:template match="product|product[@id = 'p2']">
        <xsl:comment>
            <xsl:value-of select="concat(' ', @name, ' ')" />
        </xsl:comment>
        <xsl:text>&#xA;</xsl:text>
        <xsl:next-match />
    </xsl:template>
</xsl:stylesheet>

示例输入

<?xml version="1.0"?>
<products>
    <product id="p1" name="Delta" price="3250" stock="4" />
    <product id="p2" name="Golf" price="1000" stock="5" />
    <product id="p3" name="Alpha" price="1200" stock="19" />
</products>

2 个答案:

答案 0 :(得分:3)

XSLT 2.0规范说,拥有两个具有相同优先级和优先级的模板是错误的,这两个模板都匹配同一个节点,这就是这里发生的事情。该规范为应该发生的事情提供了许多选项(Saxon具有允许您选择各种策略的配置选项),但如果您希望您的代码可移植且没有错误,最好的方法是使用显式优先级为每个规则添加xsl:template上的priority属性。 (数字越大意味着优先级越高)。

答案 1 :(得分:1)

基本上,给你的XSLT你有两次相同的匹配模式,你有xsl:template match="product"xsl:template match="product[@id = 'p2']",然后你又有了xsl:template match="product|product[@id = 'p2']"。这样,您的所有product输入元素肯定存在模糊匹配。所以我同意你的看法,在不同模板上两次具有相同匹配模式的样式表,你会得到错误或模糊警告。但是,处理器可以选择仅发出警告并选择最后一个模板。这就是Saxon 9所做的事情,例如

Recoverable error
  XTRE0540: Ambiguous rule match for /products/product[1]
Matches both "element(Q{}product)" on line 14 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl
and "element(Q{}product)" on line 8 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl
Recoverable error
  XTRE0540: Ambiguous rule match for /products/product[2]
Matches both "product|product[@id = 'p2']" on line 14 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl
and "product[@id = 'p2']" on line 11 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl
Recoverable error
  XTRE0540: Ambiguous rule match for /products/product[3]
Matches both "element(Q{}product)" on line 14 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl
and "element(Q{}product)" on line 8 of
  file:/C:/Users/Martin%20Honnen/Documents/xslt/test2014012101.xsl

然后写出

的输出
<PRODUCTS>
    <!-- Delta -->
   <PRODUCT id="p1" price="3250" stock="4"/>
    <!-- Golf -->
   <PRODUCT id="p2" price="1250" stock="5"/>
    <!-- Alpha -->
   <PRODUCT id="p3" price="1200" stock="19"/>
</PRODUCTS>