2010-09-30 64 views
4

在網上尋找答案後,提出「幾乎」的解決方案......我決定將問題簡化爲一個非常簡單的案例。未使用的命名空間聲明出現在XSLT後

考慮下面的XML片段:

<me:root xmlns:me="http://stackoverflow.com/xml" 
    xmlns="http://www.w3.org/1999/xhtml"> 
    <me:element> 
     <p>Some HTML code here.</p> 
    </me:element> 
</me:root> 

注意,p元素是XHTML的命名空間,這是該文檔的默認之一。

現在考慮下面的簡單樣式表。我想創建一個XHTML文檔,其內容爲me:element

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:me="http://stackoverflow.com/xml" 
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="me"> 
    <xsl:template match="/"> 
     <html xmlns="http://www.w3.org/1999/xhtml"> 
      <head> 
       <title>My Title</title> 
      </head> 
      <body> 
       <xsl:copy-of select="me:root/me:element/node()"/> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

注意,我包括exclude-result-prefixes ...但是看看我得到:

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <title>My Title</title> 
    </head> 
    <body> 
     <p xmlns:me="http://stackoverflow.com/xml">Some HTML code here.</p> 
    </body> 
</html> 

,什麼是我瘋狂這是爲什麼,哦,爲什麼xmlns:me出現p元素裏面?

無論我嘗試了什麼,我都無法讓東西上班。我有一個奇怪的感覺,問題是我的xsl:copy-of聲明。

+0

好問題(+1)。查看我的答案以獲得詳細的解釋和完整的解決方案。 – 2010-09-30 04:44:38

回答

6

我有一種奇怪的感覺, 問題是我xsl:copy-of 聲明。

正是這個原因。

源XML文檔包含該片段

<me:element> 
    <p>Some HTML code here.</p> 
</me:element> 

在XPath數據模型,命名空間節點從一個子樹的給其所有後代的根部繁殖。因此,<p>元件具有以下名稱空間:

  1. "http://stackoverflow.com/xml"

  2. "http://www.w3.org/XML/1998/namespace"

  3. http://www.w3.org/2000/xmlns/

最後兩個是reserved namespaces(前綴xml:xmlns),並且可用於任何命名節點。

報告的問題是由於定義<xsl:copy-of>指令使用屬於每個節點的所有名稱空間複製所有節點及其完整子樹。

記住:指定爲exclude-result-prefixes屬性的值前綴僅從字面-結果元素排除!

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:me="http://stackoverflow.com/xml" 
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="me"> 

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

    <xsl:template match="/"> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
     <head> 
     <title>My Title</title> 
     </head> 
     <body> 
     <xsl:apply-templates select="me:root/me:element/*"/> 
     </body> 
    </html> 
    </xsl:template> 

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

當這個變換所提供的XML文檔施加:

<me:root xmlns:me="http://stackoverflow.com/xml" 
    xmlns="http://www.w3.org/1999/xhtml"> 
    <me:element> 
     <p>Some HTML code here.</p> 
    </me:element> 
</me:root> 

有用,正確的結果產生

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <title>My Title</title> 
    </head> 
    <body> 
     <p>Some HTML code here.</p> 
    </body> 
</html> 
+0

即使您嘗試過,也不會更有幫助。謝謝迪米特雷 - 很好的解釋。恰到好處。 – Isaac 2010-09-30 05:32:39

+0

但是,我意識到這個解決方案存在一個缺陷:HTML元素中的屬性不會被複制......所以我現在正試圖解決這個問題。 – Isaac 2010-09-30 05:50:27

+1

@Isaac:我剛剛編輯我的答案,以複製元素的所有屬性。您可以在此處使用''而不是'',這樣可以提供更多靈活性 - 您可以使用模板來處理特定屬性。 – 2010-09-30 12:41:37