2013-06-05 60 views
1

我有一個需要更改根節點的XML文檔。用我可以刮掉網絡的小知識,我可以將事情看起來像我想要的,除了我的XML的子節點具有新的xmlns屬性。我是申請改造的XML看起來像:避免在應用XSLT時在xml響應中添加xmlns屬性

<gmd:MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" 
    xmlns:gco="http://www.isotc211.org/2005/gco" 
    xmlns:gmd="http://www.isotc211.org/2005/gmd" 
    xmlns:gmi="http://www.isotc211.org/2005/gmi" 
    xmlns:gml="http://www.opengis.net/gml" 
    xmlns:gmx="http://www.isotc211.org/2005/gmx" 
    xmlns:gsr="http://www.isotc211.org/2005/gsr" 
    xmlns:gss="http://www.isotc211.org/2005/gss" 
    xmlns:gts="http://www.isotc211.org/2005/gts" 
    xmlns:srv="http://www.isotc211.org/2005/srv" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.isotc211.org/2005/gmd 
    http://www.ngdc.noaa.gov/metadata/published/xsd/schema/gmd/gmd.xsd"> 
    <gmd:language> 
    <gmd:LanguageCode 
     codeList="http://www.loc.gov/standards/iso639-2/php/code_list.php" 
     codeListValue="eng" codeSpace="ISO639-2" 
     >eng</gmd:LanguageCode> 
    </gmd:language> 
    ...... 
</gmd:MD_Metadata> 

我的XSLT是這樣的:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:gmd="http://www.isotc211.org/2005/gmd" 
    xmlns:gco="http://www.isotc211.org/2005/gco" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:gml="http://www.opengis.net/gml" 
    xmlns:gmi="http://www.isotc211.org/2005/gmi"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <gmi:MI_Metadata 
     xmlns="http://www.isotc211.org/2005/gmi" 
     xmlns:gco="http://www.isotc211.org/2005/gco" 
     xmlns:gmd="http://www.isotc211.org/2005/gmd" 
     xmlns:gmi="http://www.isotc211.org/2005/gmi" 
     xmlns:gml="http://www.opengis.net/gml" 
     xmlns:gmx="http://www.isotc211.org/2005/gmx" 
     xmlns:gsr="http://www.isotc211.org/2005/gsr" 
     xmlns:gss="http://www.isotc211.org/2005/gss" 
     xmlns:gts="http://www.isotc211.org/2005/gts" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:srv="http://www.isotc211.org/2005/srv" 
     xsi:schemaLocation="http://www.isotc211.org/2005/gmi 
     http://www.ngdc.noaa.gov/metadata/published/xsd/schema.xsd" > 
     <xsl:for-each select="/*/node()|@*"> 
     <xsl:copy-of select="." /> 
     </xsl:for-each> 
    </gmi:MI_Metadata> 
    </xsl:template> 
</xsl:stylesheet> 

和輸出的樣子:

<gmi:MI_Metadata xmlns="http://www.isotc211.org/2005/gmi" 
     xmlns:gco="http://www.isotc211.org/2005/gco" 
     xmlns:gmd="http://www.isotc211.org/2005/gmd" 
     xmlns:gmi="http://www.isotc211.org/2005/gmi" 
     xmlns:gml="http://www.opengis.net/gml" 
     xmlns:gmx="http://www.isotc211.org/2005/gmx" 
     xmlns:gsr="http://www.isotc211.org/2005/gsr" 
     xmlns:gss="http://www.isotc211.org/2005/gss" 
     xmlns:gts="http://www.isotc211.org/2005/gts" 
     xmlns:srv="http://www.isotc211.org/2005/srv" 
     xmlns:v1="http://www.isotc211.org/2005/gmd" 
     xmlns:xlink="http://www.w3.org/1999/xlink" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.isotc211.org/2005/gmi 
     http://www.ngdc.noaa.gov/metadata/published/xsd/schema.xsd"> 
    <gmd:language xmlns="http://www.isotc211.org/2005/gmd"> 
    <gmd:LanguageCode 
     codeList="http://www.loc.gov/standards/iso639-2/php/code_list.php" 
     codeListValue="eng" codeSpace="ISO639-2" 
     >eng</gmd:LanguageCode> 
    </gmd:language> 
    ....... 
</gmi:MI_Metadata> 

我想避免的xmlns =「http://www.isotc211.org/2005/gmd」在子節點的輸出中,有沒有什麼辦法可以實現呢?我注意到,當我改變XSLT的部分:

<xsl:template match="/"> 
<gmi:MI_Metadata xmlns="http://www.isotc211.org/2005/gmd" .... 

中的xmlns消失但隨後頁眉/根節點不是客戶想要在輸出什麼!所以我不確定我能做什麼。非常感謝您的見解,謝謝。

回答

1

不管exclude-result-prefixesxsl:copy-of將複製的命名空間,每​​:

在xsl:元件的拷貝可以被用於插入結果樹片段插入到結果樹... [w]結果是一個節點集合,集合中的所有節點都按文檔順序複製到結果樹中;複製元素節點複製屬性節點,命名空間節點和元素節點以及元素節點本身的孩子......

因此,你需要複製自己做的(更)。舉例來說,這裏是一片的解決方案,一個規則來複制元素:

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

然後複製的東西,正常

<xsl:template match="node()|@*" mode="copy"> 
    <xsl:copy />  
</xsl:template> 

然後,在你的代碼,你可以做

<xsl:for-each select="/*/node()|@*"> 
    <xsl:apply-templates mode="copy" select="." /> 
</xsl:for-each> 
+0

謝謝torazaburo和@C。 M. Sperberg-McQuee爲您的迴應。我應用了torazaburo提供的xslt片段,並且能夠擺脫子節點中的xmlns屬性。我確實看到xlink:type =「simple」附屬於一些子元素,但我想我可以通過Google來處理它。再次感謝。 –

0

您可能想要閱讀exclude-result-prefixes屬性。

他們有一個默認的名稱空間聲明爲gmd名稱空間,當然,因爲他們從輸入,使該名稱空間默認(以及綁定到前綴gmd)複製。我會嘗試將xsl:copy-of更改爲更像傳統標識轉換的東西,以便您可以嘗試覆蓋子元素中的默認命名空間聲明。

<xsl:copy> 
    <xsl:for-each 
    select="$ns-carrier/namespace::*[local-name() = 'xmlns']"> 
    <xsl:copy/> 
    <xsl:for-each> 
    <xsl:for-each select="@*|node()"> 
    <xsl:copy-of select="."/> 
    </xsl:for-each> 
</xsl:copy> 

(未測試,所以藉此與一粒鹽。)

它可以幫助提醒自己(和客戶端!),除非你正在做的事情不尋常,有點髒命名空間綁定,那麼對於任何合理的XML工具鏈來說,這是一個純粹的裝飾性問題,而不是實質性問題。 (也就是說,準備告訴你自己和你的客戶,如果你不能設法讓樣式表做你想做的事情,那麼你應該告訴你自己和你的客戶真的沒有關係。通過嘗試使命名空間管理自動發生,XSLT的設計者使得它很難做手工)