2012-08-30 92 views
0

我有一個xsl模板出現問題,該模板輸出具有空xmlns屬性的節點。xsl模板 - 某些節點出現空的xmlns屬性

模板是:

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

<xsl:template match="/"> 
    <X xmlns="a_ns"> 
     <Y> 
      <xsl:value-of select="a/b/b2"/> 
     </Y> 
     <Z> 
      <xsl:copy-of select="a/d/d1/d11"/> 
     </Z> 
    </X> 
</xsl:template> 

的輸入是:

<a> 
<b> 
    <b1>b1_text</b1> 
    <b2>b2_text</b2> 
</b> 
<c> 
    <c1>c1_text</c1> 
    <c2>c2_text</c2> 
</c> 
<d> 
    <d1> 
     <d11> 
      <d111 ls="op">d111_text</d111> 
      <d112>d112_text</d112> 
     </d11> 
     <d12>d12_text</d12> 
    </d1> 
    <d2>d2_text</d2> 
    <d3>d3_text</d3> 
</d> 

的輸出:

<?xml version="1.0" encoding="utf-8"?> 
<X xmlns="a_ns"> 
    <Y>b2_text</Y> 
    <Z> 
     <d11 xmlns=""> 
      <d111 ls="op">d111_text</d111> 
      <d112>d112_text</d112> 
     </d11> 
    </Z> 
</X> 

如何修改模板以便xmlns =「」不再出現?

謝謝!

回答

3

這種轉變

<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="/"> 
     <X xmlns="a_ns"> 
      <Y> 
       <xsl:value-of select="a/b/b2"/> 
      </Y> 
      <Z> 
       <xsl:apply-templates select="a/d/d1/d11"/> 
      </Z> 
     </X> 
    </xsl:template> 

    <xsl:template match="*[ancestor-or-self::d11]"> 
    <xsl:element name="{name()}" namespace="a_ns"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<a> 
    <b> 
     <b1>b1_text</b1> 
     <b2>b2_text</b2> 
    </b> 
    <c> 
     <c1>c1_text</c1> 
     <c2>c2_text</c2> 
    </c> 
    <d> 
     <d1> 
      <d11> 
       <d111 ls="op">d111_text</d111> 
       <d112>d112_text</d112> 
      </d11> 
      <d12>d12_text</d12> 
     </d1> 
     <d2>d2_text</d2> 
     <d3>d3_text</d3> 
    </d> 
</a> 

產生想要的,正確的結果

<X xmlns="a_ns"> 
    <Y>b2_text</Y> 
    <Z> 
     <d11> 
     <d111 ls="op">d111_text</d111> 
     <d112>d112_text</d112> 
     </d11> 
    </Z> 
</X> 

說明

xsl:copy-of產生由在其select屬性中指定的表達式選擇的每個節點的精確副本。因此,它不能用於更改任何複製元素的(默認)名稱空間。

在這種情況下被複制的元素屬於「no namespace」。被拷貝的元素仍然屬於「無名字空間」的事實由XSLT處理器以xmlns=""表示 - 正確地如此 - 由XSLT處理器表示。

0

要注意的關鍵是您要更改元素的名稱,如d11。在輸入中,名稱是{} d11 - 也就是說,d11不在命名空間中,而在輸出中,您希望將其命名爲{a_ns} d11 - 即名稱空間a_ns中的d11。 xsl:copy-of指令完全複製節點,因此它保留名稱{} d11,並且序列化程序必須添加xmlns =「」聲明以確保它保留此名稱。要更改名稱(特別是名稱的名稱空間部分),需要使用Dimitre提供的過程來轉換節點而不是複製它們。