2012-12-20 31 views
1

我有一種比較麻煩的這個比我要和一直沒能找到,這似乎是正確的解決方案的命名空間:更改使用XSLT 1

我想簡單地改變XML的命名空間使用xslt 1.0的文檔 - 使用java應用程序,使用javax.xml.transform。

這是我的xml文檔:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Root xmlns="http://namespace1.org" type="Document" version="V2_2"> 
    <Content> 
     <Text>asdf</Text> 
    </Content> 
</Root> 

這是它應該如何看改造後:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Root xmlns="http://namespace2.org" type="Document" version="V2_2"> 
    <Content> 
     <Text>asdf</Text> 
    </Content> 
</Root> 

這是我的XSLT代碼:

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

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

</xsl:stylesheet> 

這是轉化後得到的實際產量:

<?xml version="1.0" encoding="UTF-8"?> 
<ns0:Root xmlns:ns0="http://namespace2.org">2012-11-02T15:39:46.05+01:00DocumentV2_2<ns1:Content xmlns:ns1="http://namespace2.org"> 
    <ns2:Text xmlns:ns2="http://namespace2.org">asdf</ns2:Text> 
</ns1:Content> 
</ns0:Root> 

有辦法很多前綴補充說,這是我不想要的。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://namespace2.org" 
xmlns:cmp="http://namespace2.org" 
exclude-result-prefixes="cmp"> 

    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*"> 
    <xsl:element name="cmp:{name()}" namespace="http://namespace2.org"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 

</xsl:stylesheet> 

產生以下輸出:

我已經能夠通過以下XLST擺脫NS +增量前綴

<?xml version="1.0" encoding="UTF-8"?> 
<cmp:Root xmlns:cmp="http://namespace2.org" type="Document" version="V2_2"> 
<cmp:Content> 
    <cmp:Text>asdf</cmp:Text> 
</cmp:Content> 
</cmp:Root> 

但我一直沒能擺脫'cmp'前綴。

任何想法如何實現所需的輸出?

+1

我很好奇 - 如果你使用的是Java,那麼爲什麼在地球上,你仍然在使用XSLT 1.0嗎? –

回答

2

這個通用的轉型(適用於任何XML文檔,以及新的命名空間爲全局/外部參數傳遞):

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

<xsl:param name="pNewNS" select="'http://namespace2.org'"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

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

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

<xsl:template match="@*[namespace-uri()=namespace-uri(/*)]"> 
    <xsl:attribute name="{name()}" namespace="{$pNewNS}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<Root xmlns="http://namespace1.org" type="Document" version="V2_2"> 
    <Content> 
     <Text>asdf</Text> 
    </Content> 
</Root> 

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

+0

不幸的是我無法驗證這一點。這是我的xslt輸出:<?xml version =「1.0」encoding =「UTF-8」?>; asdf;可能這是xslt變壓器的java實現問題? –

+0

@codeySmurf,W3C XSLT 1.0規範並不阻止XSLT處理器向元素名稱添加生成的名稱空間前綴。和一些XSLT處理器一樣,您正在使用的處理器會爲元素名稱添加前綴,並且不會生成默認名稱空間。作爲結果得到的文檔和我得到的文檔是完全相同的文檔 - 它們在詞彙表示方面只有不同。我使用了Saxon 6.5.4,並得到了我複製並粘貼到答案中的結果。我的計算機上安裝了所有12個XSLT處理器,結果完全相同。 –

+0

@codeySmurf我得到了與我的計算機上安裝的所有12個XSLT處理器完全相同的結果MSXML 3/4/6,.Net XslCompiledTransform和XslTransform,Saxon 6.5.4,9.1.07,9.4.06,.NET,Altova (XML-SPY XSLT 1.0和XSLT 2.0),XQSharp。 –