2011-06-06 65 views
4

我有一個如下所示的xml。如何在xsl翻譯時忽略命名空間

<?xml version="1.0" encoding="UTF-8"?> 
<books xmlns="http://www.books.com/SRK"> 
    <name>English</name> 
</books 

我需要使用xsl進行翻譯後的以下輸出。

<?xml version="1.0" encoding="UTF-8"?> 
<books> 
    <name>English</name> 
</books> 

我需要一個xsl來忽略命名空間。我嘗試了一些東西,但它沒有與命名空間一起工作。

我需要你的幫助。你的幫助將不勝感激。

+3

歡迎SO。發佈代碼時,請縮進4個空格或在編輯器中使用「{}」按鈕,以便正確顯示。我爲你修好了。 – 2011-06-06 14:42:11

+0

您可以發佈更復雜的輸入樣本嗎? – 2011-06-11 05:26:28

回答

5

這種轉變

<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:template match="@*|node()[not(self::*)]"> 
    <xsl:copy/> 
</xsl:template> 

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

當應用於提供的XML文檔

<books xmlns="http://www.books.com/SRK"> 
    <name>English</name> 
</books> 

產生想要的,正確的結果

<books> 
    <name>English</name> 
</books> 
+0

你能解釋一下'[not(self :: *)]'的需要嗎?我已經測試沒有它,它也適用。 (+1) – 2011-06-06 14:43:38

+0

似乎也只有第二個模板是必要的。我對嗎? – 2011-06-06 14:47:48

+0

@empo:對於這個特定的XML文檔,只需要第二個模板就會生成想要的結果。但是,XML文檔通常具有:屬性,註釋節點,PI節點。我的解決方案適用於任何具有這些類型節點混合的XML文檔。 – 2011-06-06 15:59:19

2

其工作只有當我包括上述模板,如果我添加一些其他模板比以上一個,那麼翻譯是不是工作。沒有模板得到執行。

可能您錯過了book元素的名稱空間聲明。例如:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:b="http://www.books.com/SRK" 
    exclude-result-prefixes="b"> 

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

     <!-- @dimitre's answer templates --> 

    <xsl:template match="b:name"> 
      <!-- your template for name --> 
    </xsl:template> 

</xsl:stylesheet> 

此外,請務必使用local-name()函數來獲取元素的名稱,沒有相關的命名空間。


<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:b="http://www.books.com/SRK" 
    exclude-result-prefixes="b"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 


    <xsl:template match="b:input"> 
     <xsl:element name="{local-name(.)}"> 
       <xsl:apply-templates select="b:name"/> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="b:name"> 
     <xsl:element name="{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:element> 
      <lhs> 
       <xsl:apply-templates select="following-sibling::b:lhs/b:evaluate"/> 
      </lhs> 
    </xsl:template> 

    <xsl:template match="b:evaluate"> 
     Something to evaluate...  
    </xsl:template> 

</xsl:stylesheet> 

得到:

<?xml version="1.0" encoding="UTF-8"?> 
<input> 
<name>English</name> 
<lhs> 
     Something to evaluate...  
    </lhs> 
</input> 

第二示例

您可以創建一個名爲local @ identity.xsl的單獨轉換,其中包含@Dimitre解決方案。然後你可以在你的轉換中導入它。因爲你有一個命名空間,搭配元素,你必須改變所有您的XPath,包括您將在變換聲明前綴,如下面的例子:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:brl="http://www.xyz.com/BRL" 
    exclude-result-prefixes="brl" 
    version="1.0"> 

    <xsl:import href="local-identity.xsl"/> 

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


    <xsl:template match="/brl:rule"> 
    <!-- do your staff, select using brl prefix --> 
    <xsl:apply-templates/> 
    </xsl:template> 

</xsl:stylesheet> 
+1

使用exclude-result-prefixes =「b」的想法幫助我解決了一個相關的問題。謝謝! – louisgab 2016-11-28 14:06:13