2010-06-30 64 views
2

XSL樣式表應該如下代碼到Internet Explorer輸出:如何在XSLT輸出中保留XML命名空間?

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 

但是,當我執行與任何XML

<xsl:template match="*|node()"> 
    <xml:namespace prefix="vml" 
        ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 

IE下面的模板拋出分析錯誤:樣式表不包含文檔元素。 在同一時間火狐刪除輸出XML命名空間 ...

那麼,怎樣才能保持我的xml 命名在我的輸出?

重要

一個。我使用的輸出方法是html

b。以下代碼不能解決我的問題:

<xsl:template match="*|node()"> 
    <namespace prefix="vml" 
       xmlns="http://www.w3.org/XML/1998/namespace" 
       ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
+0

難道我理解正確的話,你想一個命名空間節點添加到每個元素? – 2010-06-30 13:29:32

+0

@Sawa:我必須說我與Dimitre有關,不鼓勵MS允許使用xml:namespace和其他非標準元素。更重要的是,這可以通過適當的命名空間聲明'xmlns:vml =「urn:schemas-microsoft-com:vml」' – 2010-06-30 18:52:47

回答

2

您不能使用保留的xml前綴。使用這樣的事情:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dummy="dummy"> 
<xsl:namespace-alias stylesheet-prefix="dummy" result-prefix="xml"/> 
<xsl:template match="/"> 
    <dummy:namespace prefix="vml" 
        ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
</xsl:stylesheet> 

與任一輸入,你會得到這樣的結果:如果你硬是要如圖所示的問題,結果

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml" /> 
1

,這是非常簡單的實現

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

<xsl:template match="/"> 
    <xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 
</xsl:template> 
</xsl:stylesheet> 

這種轉變,當在任何XML文檔(未使用)被應用時產生的有用結果

<xml:namespace prefix="vml" ns="urn:schemas-microsoft-com:vml"/> 

然而,在我看來,你想一個命名空間節點添加到給定的XML文檔中的每個元素(如果不是這樣,只是讓我通過commentand我會刪除該知道回答)。

如果是這樣,這裏是一個簡單且有效的方式:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:vml="urn:schemas-microsoft-com:vml" 
    exclude-result-prefixes="vml"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:variable name="vNamespace" select= 
    "document('')/*/namespace::*[name()='vml']"/> 

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

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

當施加到任何文件,例如這一個

<t> 
    <a x="3"> 
     <b y="4"/> 
    </a> 
</t> 

有用結果產生

<t xmlns:vml="urn:schemas-microsoft-com:vml"> 
    <a x="3"> 
     <b y="4"/> 
    </a> 
</t> 

由於只有結果的頂部元素明顯具有所需的名稱空間節點,因此這可能會使第一次看到時感到困惑。但是,根據定義(查看XML Namespace spec)如果(子)樹根上的元素具有給定的命名空間節點,則其所有的後代元素也都具有該命名空間節點。即使您將名稱空間複製到每個元素,XSLT序列化器也會從除頂部元素之外的所有元素的序列化(文本)表示中剝離它。

在XSLT 2.0則只需使用<xsl:namespace>指令

<xsl:namespace name="vml" select="urn:schemas-microsoft-com:vml"/> 
+0

我認爲你的回答並不包括所有情況。如果樣式表必須使用IE瀏覽器進行客戶端解析,那麼您會得到以下結果:'El prefijo del espacio de nombres no puede comenzar con la cadena reservada'xml「' – 2010-06-30 14:47:37

+1

@Ajjandro:我沒有意識到MSXML3的這種行爲哪些IE使用)。嗯......這可能被認爲是一個功能和一個錯誤。事實上,我所使用的所有其他XSLT處理器都允許這樣做。事實上MSXML4允許這樣做,這意味着它們糾正了MSXML4中的MSXML3錯誤。沒關係,試圖在'xml:'命名空間中使用非標準元素是一種粗暴的濫用,我不鼓勵作者這麼做。 – 2010-06-30 16:13:37

+0

我和你一起勸說不要使用MS所允許的'xml:namespace'和其他非標準元素。更重要的是,這可以通過適當的命名空間聲明'xmlns:vml =「urn:schemas-microsoft-com:vml」' – 2010-06-30 18:51:37