2009-02-16 93 views
4

我正在使用XSLT重新构建XML文件。下面的代码将所有子节点到一个新的XML文件:XSLT中的命名空间

<!--Add all child elements of the zzz node--> 
<xsl:template match="zzz"> 
    <Trade> 
     <xsl:attribute name="ID"> 
      <xsl:value-of select="TradeId" /> 
     </xsl:attribute> 
     <xsl:copy-of select="*"></xsl:copy-of> 
    </Trade> 
</xsl:template> 

我想修改代码,以便它把节点到一个特定的命名空间不是源文件内。我需要改变什么?

回答

5

前两个答案(由teun和Craig Bovis)是不正确的 - 请参阅我对每个问题的评论。

到给定的元件移动到一个新的命名空间中的corect方式涉及重新创建该元素如下所示

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

    <xsl:template match="zzz"> 
     <trade ID="{TradeId}"> 
     <xsl:apply-templates select="*[not(self::TradeId)]"/> 
     </trade> 
    </xsl:template> 

    <xsl:template match="zzz/*"> 
     <xsl:element name="{name()}" namespace="my:Trade"> 
     <xsl:copy-of select="@* | node()"/> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

当在下面的源XML文档施加这种转变:

<zzz> 
    <TradeId>153</TradeId> 
    <x:item xmlns:x="x:x">A</x:item> 
    <x:item xmlns:x="x:x">B</x:item> 
    <x:item xmlns:x="x:x">C</x:item> 
</zzz> 

所需的结果产生

<trade ID="153"> 
    <x:item xmlns:x="my:Trade">A</x:item> 
    <x:item xmlns:x="my:Trade">B</x:item> 
    <x:item xmlns:x="my:Trade">C</x:item> 
</trade> 
0

您可以直接在您的样式表的命名空间,如下所示:

<!--Add all child elements of the zzz node--> 
<xsl:template match="zzz" xmlns:my="your target ns"> 
<my:Trade> 
<xsl:attribute name="my:ID" > 
<xsl:value-of select="TradeId" /> 
</xsl:attribute> 
<xsl:copy-of select ="*"></xsl:copy-of> 
</my:Trade> 
</xsl:template> 

编辑:Dimitre指出,这将地方复制的节点进入新的命名空间,只有贸易的元素。

+0

非常不正确:1. OP明确表示他希望仅在匹配元素的子节点中放入新名称空间 - 而不是任何属性。 2. 中复制的元素仍然不属于这个新的名称空间。 – 2009-02-16 17:58:27

+0

啊,对。我误解了这个问题。谢谢,Dimitre。 – 2009-02-17 08:07:17

0

Dimitre Novatchev的解决方案是好的,但我还要指出的是,如果你需要改变嵌套元素的命名空间太大,下面将更好地工作:

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

    <xsl:template match="zzz"> 
    <trade ID="{TradeId}"> 
     <xsl:apply-templates select="*[not(self::TradeId)]" mode="change-ns"/> 
    </trade> 
    </xsl:template> 

    <xsl:template match="@*|node()" priority="-10" mode="change-ns"> 
    <xsl:copy/> 
    </xsl:template> 

    <xsl:template match="*" mode="change-ns"> 
    <xsl:element name="{name()}" namespace="my:Trade"> 
     <xsl:apply-templates select="@*|node()" mode="change-ns"/> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

例如如果你有以下输入文档

<trade ID="153"> 
    <x:item xmlns:x="my:Trade" someattr="1"> 
    <x:subitem anotherattr="2">A1</x:subitem> 
    <x:subitem anotherattr="3">A2</x:subitem> 
    </x:item> 
    <x:item xmlns:x="my:Trade">B</x:item> 
    <x:item xmlns:x="my:Trade">C</x:item> 
</trade> 

你会得到

<zzz> 
    <TradeId>153</TradeId> 
    <x:item xmlns:x="x:x" someattr="1"> 
    <x:subitem anotherattr="2">A1</x:subitem> 
    <x:subitem anotherattr="3">A2</x:subitem> 
    </x:item> 
    <x:item xmlns:x="x:x">B</x:item> 
    <x:item xmlns:x="x:x">C</x:item> 
</zzz> 

属性添加,以证明他们是正确复制,并用于命名空间改变模板分离模式,让他们不要”如果您想将它们用作较大样式表的一部分,则不会干扰其他代码。