XSLT:为什么/ * / *会覆盖/ * / x?

时间:2014-02-08 04:54:24

标签: xml xslt

我正在研究XSLT,我遇到了以下问题。我有这个XML:

<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/>

应该转换为thix xml,使用XSLT 1.0:

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

这是我的尝试:

    <?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>

但是当我应用此转换,并且程序将转换x元素时,它将应用此模板:/ * / *而不是/ * / x。

我知道/ * / *匹配根的每个“子”,但是从我所知道的/ * / x应该具有x元素的优先级。你能帮我理解我的XSLT有什么问题吗?

感谢您的帮助!

编辑: 例如,如果我有这个输入:

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

我应用此转换:

<?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”,“b”,“c”按照我的预期匹配

1 个答案:

答案 0 :(得分:4)

答案是两者都没有优先权。请查看XSLT建议书,了解模板优先级如何工作的详细信息(它比您预期的要复杂得多),并且在有疑问时明确设置优先级。

http://www.w3.org/TR/xslt#conflict

或者,从2.0规范,但基本上相同,可能更具可读性:

http://www.w3.org/TR/xslt20/#conflict