XSLT:为什么/ * / *覆盖/ * / x和*不会遍及x?

时间:2014-02-08 22:02:32

标签: xml xslt

我试图理解以下两个例子之间的差异。我不明白为什么在第一种情况下x与match="x"模板匹配,而在第二种情况下,X元素由/*/*而不是/*/x匹配。这是代码:

第一个例子,输入文件:

<a> <c> <a> 
    <b>1</b>
    <b>2</b>
</a>
    <f><b>3</b>
    </f>
</c>
    <b> <c>4</c> 5 </b>
</a>

第一个例子,XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="a">
        <A><xsl:apply-templates/></A> 
    </xsl:template>
    <xsl:template match="b"> 
        <B><xsl:value-of select="."/></B>
    </xsl:template>
    <xsl:template match="c"> 
        <xsl:apply-templates/> 
    </xsl:template>
    <xsl:template match="*"> 
        <xsl:element name="{name()}"><xsl:apply-templates/></xsl:element>
    </xsl:template>
</xsl:stylesheet>

第二个例子,输入文件:

<a>
<x>testo 0
    <rad>testo 1</rad>
</x>
<b>
    <p>
        <w>
            <z>testo 2</z>
        </w>
    </p>
</b>
<y>
    <p/>
    <y>testo 3
        <d>testo 4</d>
    </y>
</y>
<f/>

第二个例子,XSLT:

  <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:template match="/*">
            <xsl:element name="r">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="/*/x">
        <nx><xsl:element name="oldx"/>
        <xsl:apply-templates/></nx>
    </xsl:template>
    <xsl:template match="/*/y">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="/*/*">
        <xsl:element name="{name()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="/*/*/*">
        <new>
            <xsl:element name="{name()}"/>
            <xsl:apply-templates/>
        </new>
    </xsl:template>
    <xsl:template match="text()">
        <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="*">
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

第二个文件的输出应该是以下文件,我只能将条件[name()!='x' and name()!='y']应用于/* /*匹配模板。如果我不应用此条件,则在输入文件中找到X元素时,XSLT文件将应用/* /*模板而不是/* /x模板,如第一个示例中所示。这两个例子有什么区别? 谢谢!

第二个例子的预期输出:

<r>
<nx>
<oldx/>
<new>
<rad/>
</new>
</nx>
<b>
<new>
<p/>
</new>
</b>
<new>
<p/>
</new>
<new>
<y/>
</new>
<f/>
</r>

1 个答案:

答案 0 :(得分:1)

http://www.w3.org/TR/xslt20/#conflict解释了当多个是可能的选择时解决模板匹配的规则。它们比你想象的要简单。

在许多情况下,您有责任明确使用priority=属性来帮助澄清哪个模板优先,或使用modes选择哪个模板在哪个模板中处于活动状态给定时间,或重写样式表,使匹配更明确,不会相互冲突。