2012-08-30 45 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提供的过程来转换节点而不是复制它们。