2014-02-10 150 views

回答

2

至少有一個區別。鑑於以下輸入:

<root xmlns="htpp://www.example.com/my">my text</root> 

這個模板:

<xsl:template match="/*"> 
    <xsl:element name="{name()}"> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

會產生:

<root>my text</root> 

xsl:copy將複製其命名空間的元素保留:

<root xmlns="htpp://www.example.com/my">my text</root> 

編輯
在響應由@parakmiakos評論:

鑑於以下輸入:

<my:root xmlns:my="htpp://www.example.com/my">my text</my:root> 

這個模板*:

<xsl:template match="/*"> 
    <xsl:element name="{name()}"> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

會產生:

<my:root xmlns:my="htpp://www.example.com/my">my text</my:root> 

(*)前提是在樣式表中聲明瞭「我的」前綴。

這個模板:

<xsl:template match="/*"> 
    <xsl:element name="{local-name()}"> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

會產生:

<root>my text</root> 

這一個:

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

將返回:

<my:root xmlns:my="htpp://www.example.com/my">my text</my:root> 

與第一個相同(但不必聲明前綴)。

+0

我認爲通過使用name()而不是local-name(),他會保留名稱空間。 – parakmiakos

+0

@parakmiakos http://xsltransform.net/6qM2e2b/1 –

+0

有趣的是,我用的工具沒有這樣工作。 – parakmiakos

1

xsl:element元素生成一個新的元素節點。

xsl:copy將上下文項目複製到輸出序列。但是,所述上下文項不必是元素節點。在你的情況下:

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

上下文項目確實是一個元素。這會帶來以下後果:如果任何

  • 如果上下文項是元素用於內部xsl:copy可選序列構造

    • xsl:copy還複製元素的命名空間。在實施例中,順序構造是<xsl:apply-templates/>

    摘要xsl:copy可以複製任何種類節點(原子值,文檔,元素,文本,屬性,處理指令,註釋,命名空間)的而xsl:element是完全能夠產生元素節點。

    用法:使用xsl:copy可以將節點從輸入XML有效地複製到輸出序列。僅在元素名稱爲動態時使用xsl:element,即事先未知。

    請注意,使用XSLT 2.0,您可以使用屬性copy-namespacesinherit-namespaces明確控制名稱空間的處理。

  • 1

    當您在作用域中有名稱空間聲明(除了要複製的元素的名稱空間之外)時,區別很明顯。使用<xsl:copy>將複製任何範圍內的命名空間節點,使用<xsl:element>不會。因此,考慮的

    <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
        <foo/> 
    </root> 
    

    輸入文件的

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
        <xsl:template match="/"> 
        <xsl:apply-templates select="*/*" /> 
        </xsl:template> 
    
        <xsl:template match="foo"> 
        <xsl:copy/> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    一個樣式表,你會得到的

    <?xml version="1.0"?> 
    <foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /> 
    

    因爲<xsl:copy>輸出複製了從輸入元素作用域內的命名空間節點。而如果你使用

    <xsl:template match="foo"> 
        <xsl:element name="{name()}" namespace="{namespace-uri()}"/> 
        </xsl:template> 
    

    你會得到

    <?xml version="1.0"?> 
    <foo/> 
    

    正如Matthias points out,在XSLT 2.0可以說<xsl:copy copy-namespaces="no">打壓範圍的命名空間的複製 - 對元素節點,<xsl:copy copy-namespaces="no">具有相同效果爲<xsl:element name="{name()}" namespace="{namespace-uri()}">

    相關問題