2010-12-02 87 views
2

我想使用xslt轉換輸入xml文件,以更改可以出現在xml樹的不同位置的特定元素的名稱。如何從屬於它們的非空名稱空間中刪除名稱?

我有一個像下面這樣的XML,

<catalog> 
<cd> 
    <ost:title>Empire Burlesque</ost:title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company> 
    <ost:name>Columbia<ost:name> 
    </company> 
    <price>10.90</price> 
    <year>1985</year> 
</cd> 
</catalog> 

我想刪除所有「OST:」從所有元素前綴,因爲它是使用XSLT保持一切。一個示例代碼將不勝感激。

+0

縮進4個空格或使用101010按鈕輸入代碼。我爲你修好了。 – 2010-12-02 05:05:07

+0

你好,是的,我們有ost的名字空間。實際上,我們希望將xml恢復到不支持此ost名稱空間的以前版本。感謝您的回覆 – Hasif 2010-12-02 05:13:29

回答

2

在您的示例中,您似乎沒有其他要刪除的名稱空間。所以,下面是一個XSLT樣式表的示例,它從元素中刪除了所有名稱空間(不僅僅是您的ost:)。

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- identity template: copy everything as is... --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- ... except for elements, 
     create a similarly named element without a namespace --> 
    <xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

它使用identity transformation複製一切按原樣,但是將覆蓋爲元素,創造出具有相同本地名的元素,但沒有命名空間。

如果您只想刪除ost:名稱空間,則可以包含該名稱空間的名稱空間聲明,並將後一個模板更改爲匹配ost:*

0

這種轉變是最一般的。它從全局參數中指定的名稱空間中刪除所有元素和屬性。它也消除了那些這些命名空間之一所有名稱空間節點:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" > 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:delNs> 
    <ns>some:namespace1</ns> 
    <ns>some:namespace3</ns> 
</my:delNs> 

<xsl:variable name="vdelNS" 
    select="document('')/*/my:delNs/*"/> 

<xsl:template match="*"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
    <xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@*"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template priority="10" match= 
"*[namespace-uri()=document('')/*/my:delNs/*]"> 

    <xsl:element name="{local-name()}"> 
    <xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match= 
"@*[namespace-uri()=document('')/*/my:delNs/*]"> 
    <xsl:attribute name="{local-name()}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在下面的XML文檔施加(基於所提供的,但是校正爲良好和擴展爲包含3個命名空間和在其中的元素和屬性):

<catalog xmlns:ost="some:namespace1" 
    xmlns:x="some:namespace2" 
    xmlns:y="some:namespace3"> 
<cd> 
    <ost:title>Empire Burlesque</ost:title> 
    <y:artist>Bob Dylan</y:artist> 
    <country>USA</country> 
    <company ost:type="big"> 
    <ost:name>Columbia</ost:name> 
    </company> 
    <x:price>10.90</x:price> 
    <year>1985</year> 
</cd> 
</catalog> 

有用結果產生

<catalog xmlns:x="some:namespace2"> 
    <cd> 
     <title>Empire Burlesque</title> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
     <company type="big"> 
     <name>Columbia</name> 
     </company> 
     <x:price>10.90</x:price> 
     <year>1985</year> 
    </cd> 
</catalog> 

說明

  1. 前兩個模板是幾乎等同於身份的規則,但他們不復制命名空間節點爲<my:delNs>指定的命名空間。

  2. 最後兩個模板適用於屬於<my:delNs>下列出的名稱空間的所有元素和屬性。只有在這兩個模板名稱實際上更改爲只有本地名稱。

相關問題