2011-04-08 183 views
4

嗨我正在寫一個XSLT,並在其中使用<xsl:copy-of>函數。現在,當它被執行時,來自XML的namesapce也被複制。爲了刪除我使用的功能,如<xsl:copy-of select="$RootNode/Child" copy-namespaces="no"/>。但是如果Child有更多的子元素,那麼名稱空間就出現在那裏。所以任何人都可以請告訴我如何刪除。 下面是我使用的xslt和XML的片段。命名空間從XSLT中刪除

<xsl:template match="/"> 
    <xsl:element name="Parent"> 
    <xsl:copy-of select="Child" copy-namespaces="no"/> 
    </xsl:element> 

和XML是:

<Child> 
<GrandChild> 
<PhoneNumberType>DayPhone</PhoneNumberType> 
</GrandChild></Child> 

命名空間中不出現CustomerParty,但它們存在於兒童,但他們在目前的孫子輩。

+1

問得好,+1。請參閱我的答案以獲得解釋和完整,簡短的解決方案。 :) – 2011-04-08 13:13:20

+0

Vivek:我的回答對你有用嗎?你還有什麼問題嗎?請告訴我。 – 2012-05-31 22:01:31

回答

9

copy-namespaces="no"屬性不去掉所有名稱空間節點 - 如在XSLT 2.0 spec注意到:

如果需要的值沒有,則沒有一個命名空間節點的複製:然而,命名空間節點仍然會按照命名空間修復過程的要求在結果樹中創建:請參見5.7.3命名空間修復。此屬性影響由此指令複製的所有元素:兩個元素都由選擇表達式直接選擇,而元素是由選擇表達式選擇的節點的後代。

下面是一個例子,如何擺脫所有的(非強制)命名空間節點的:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

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

<xsl:template match="@*"> 
    <xsl:attribute name="{local-name()}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

當這個一般變換此XML文檔的應用:

<x:nums xmlns:x="my:x"> 
    <x:num>01</x:num> 
    <x:num>02</x:num> 
    <x:num>03</x:num> 
    <x:num>04</x:num> 
    <x:num>05</x:num> 
    <x:num>06</x:num> 
    <x:num>07</x:num> 
    <x:num>08</x:num> 
    <x:num>09</x:num> 
    <x:num>10</x:num> 
</x:nums> 

想要的,產生正確的結果:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

請注意

  1. 轉型是不是XSLT-2.0 - 特有的,可以用XSLT 1.0使用了。

  2. 刪除所有命名空間節點通常是一個不安全的進程,因爲來自不同命名空間的節點都放在「無命名空間」中。在這個過程中,某些屬性可能會丟失,並且過程通常不可逆(不是1:1)。

+0

+1正確答案。但我認爲你的意思是[保留前綴和名稱空間名稱](http://www.w3.org/TR/xml-names/#xmlReserved)而不是_「mandatory」_ – 2011-04-08 16:30:25

+0

@Ajjandro:是的。 – 2011-04-08 16:54:11

0

有了這個模板,你應該能夠刪除的命名空間:

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

另請參考:http://www.devang-gandhi.net/blog/remove-namespace-attribute-from-xml-root-xslt/

這是否幫助你解決問題?

最好的問候, 彼得

+0

該代碼段不處理名稱空間中的屬性。 – 2011-04-08 13:15:21

+0

@Dimitre:你說得對Dimitre。謝謝您的回答。 (+1)我只是看着那個並意識到它。到目前爲止,我只需要這幾次,它總是爲我工作,只從元素中刪除名稱空間。我將它添加到我的最愛,所以我記得;-) – Peter 2011-04-08 13:20:42

+0

不客氣。 – 2011-04-08 15:48:08