为什么 <xsl:template match= "*" >竞争更具体的模板?



我有一个复杂的样式表集合,用于从各种XML文件创建SQL插入语句。XML文件可以有多种模式。我有几个模板来处理这些模式,尽管我可能会收到无法识别的XML。对于这种情况,我有一个默认模板,它只匹配"*&";。我发现这个默认模板有时优先于更具体的模板此外,当我注释掉默认模板时,更具体的模板会成功匹配。强制优先级没有帮助我正在运行Saxon HE 9.6。如果我也使用9.9,就会发生这种情况。

模板

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>

<xsl:template match="article/front"> <!-- loses to default -->
<xsl:text>article/front matched</xsl:text>

</xsl:template>

<xsl:template match="header"> <!-- wins against default -->
<xsl:text>header matched</xsl:text>

</xsl:template>

<xsl:template match="*">
<xsl:text>DEFAULT MATCH</xsl:text>
</xsl:template>

</xsl:stylesheet>

我不能提供完整的XML,但这里有一些实物模型:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE header SYSTEM "http://ej.slop.org/dtd/header.dtd">
<header>
<notification type="new" timestamp="2020-02-27 00:59:35"/>
</header>
<article xml:lang="en" article-type="research-article" dtd-version="1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
<front>
<journal-meta>
<journal-id journal-id-type="publisher-id">CLM</journal-id>
</journal-meta>
</front>
</article>

好吧,我用Saxon HE 9.9.1.4J测试了它,一切都按预期进行。

  1. 如果是第一个XML,结果是

    标头匹配

    这是正确的,因为<xsl:template match="header">规则与<header>根元素匹配。然后结束。

  2. 在第二个XML的情况下,结果是

    默认匹配

    这也是正确的,因为它将根元素<article><xsl:template match="*">规则相匹配。然后结束。规则<xsl:template match="article/front">不适用,因为它只适用于具有<article>父级的<front>元素。模板链中没有<front>元素,因为*规则不调用xsl:apply-templates

所以一切正常。

如果注释掉<xsl:template match="*">规则,则将应用内置的模板规则。这里相关的是

<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>

此规则将下降到树中,直到另一个规则匹配为止。这里是<xsl:template match="article/front">,它会给你的结果

文章/正面匹配

使用您的第二个XML。第一个结果保持不变。

最新更新