应用模板模糊匹配警告
apply-templates ambiguous match warning
我收到警告
ambiguous rule match
来自模板 copyReference 和 identity transform.
的处理器
<xsl:template name="processChildNodes">
<xsl:param name="El"/>
<xsl:for-each select="$El/node()">
<xsl:choose>
<xsl:when test="@sameas">
<xsl:apply-templates mode="copyReference" select="id(substring-after(@sameas, '#'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="copyReference" name="copyReference">
<xsl:copy>
<xsl:apply-templates select="@* except (@stem.dir, @stem.sameas)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*" mode="#all">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
这是一个 xml 片段:
<layer>
<note oct="3" pname="b" stem.dir="up" stem.sameas="#note_17544b" xml:id="note_17544"/>
</layer>
<layer>
<note oct="4" pname="d" xml:id="note_17592"/>
<note sameas="#note_17544" xml:id="note_17544b"/>
</layer>
我想做的只是复制从不带@stem.dir 和@stem.sameas 的@sameas-attribute 引用的节点。可能有不同的节点 local-names() 将被应用到其上。所以我宁愿不在 copyReference 模板的 @match-attribute 中指定节点名称。我想如果我用@select-attribute 传递我需要的节点并添加@mode,它将只匹配我需要的。实际上它有效,但当我收到警告时,应该是出了什么问题。
node()
是 *|text()|comment()|processing-instruction()
的简写,因此因为身份模板上有 mode="#all"
,它将匹配任何与 [=32= 具有相同优先级的元素] 使用 "copyReference" 模式时的模板。
解决方案取决于您的样式表的其他功能,但有多种可能性
- 从身份模板中删除
mode="#all"
(这仅在您的 XSLT 中没有其他模式时有效)
- 将
priority="2"
添加到您的 "copyReference" 模板,以便在使用模式 "copyReference" 时,您的特定模板将获得优先权。
- 将
<xsl:apply-templates mode="copyReference"...
改为 xsl:for-each
并取消模板匹配。
- 更改 "copyReference" 模板以显式匹配 "note" 而不是“*”,因为这会赋予它更高的优先级(但这显然假设您只需要匹配
note
元素)
我收到警告
ambiguous rule match
来自模板 copyReference 和 identity transform.
的处理器<xsl:template name="processChildNodes">
<xsl:param name="El"/>
<xsl:for-each select="$El/node()">
<xsl:choose>
<xsl:when test="@sameas">
<xsl:apply-templates mode="copyReference" select="id(substring-after(@sameas, '#'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" mode="copyReference" name="copyReference">
<xsl:copy>
<xsl:apply-templates select="@* except (@stem.dir, @stem.sameas)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*" mode="#all">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
这是一个 xml 片段:
<layer>
<note oct="3" pname="b" stem.dir="up" stem.sameas="#note_17544b" xml:id="note_17544"/>
</layer>
<layer>
<note oct="4" pname="d" xml:id="note_17592"/>
<note sameas="#note_17544" xml:id="note_17544b"/>
</layer>
我想做的只是复制从不带@stem.dir 和@stem.sameas 的@sameas-attribute 引用的节点。可能有不同的节点 local-names() 将被应用到其上。所以我宁愿不在 copyReference 模板的 @match-attribute 中指定节点名称。我想如果我用@select-attribute 传递我需要的节点并添加@mode,它将只匹配我需要的。实际上它有效,但当我收到警告时,应该是出了什么问题。
node()
是 *|text()|comment()|processing-instruction()
的简写,因此因为身份模板上有 mode="#all"
,它将匹配任何与 [=32= 具有相同优先级的元素] 使用 "copyReference" 模式时的模板。
解决方案取决于您的样式表的其他功能,但有多种可能性
- 从身份模板中删除
mode="#all"
(这仅在您的 XSLT 中没有其他模式时有效) - 将
priority="2"
添加到您的 "copyReference" 模板,以便在使用模式 "copyReference" 时,您的特定模板将获得优先权。 - 将
<xsl:apply-templates mode="copyReference"...
改为xsl:for-each
并取消模板匹配。 - 更改 "copyReference" 模板以显式匹配 "note" 而不是“*”,因为这会赋予它更高的优先级(但这显然假设您只需要匹配
note
元素)