2016-02-26 265 views
2

我有一个XML:XSLT添加属性为xml根节点

<doc> 
    <tag1> 
     <tag11>1</tag11> 
     <tag12>abc</tag12> 
     <tag13>test</tag13> 
     <tag14>content</tag14> 
     <tag15>2-</tag15> 
     <tag16>content</tag16> 
     <tag17> 
     <tag171>TITLE</tag171> 
     <tag172>T3</tag172> 
     <tag173>No</tag173> 
     <tag17> 
     <tag18 id="t/9905">aaa</tag18> 
     <tag18 id="t/9905">bbb</tag18> 
    </tag1> 
    <tag2> 
     <tag21>2016</tag21> 
     <tag22> 
     <tag221>1</tag221> 
     <tag222>OMG</tag222> 
     </tag22> 
     <tag23> 
     <tag231>Test</tag231> 
     <tag232>2016-01-18T00:00:00</tag232> 
     <tag233>This is a test</tag233> 
     </tag23> 
    </tag2> 
</doc> 

我想的属性(命名空间)添加到根元素:/ DOC使得输出将如下所示:

<doc xmlns="urn:test"> 
    <tag1> 
     <tag11> 
     <othertags /> 
     </tag11> 
    </tag1> 
    <tag2> 
     <tag21> 
     <othertags2 /> 
     </tag21> 
    </tag2> 
</doc> 

我试过三个xslt(跳过默认复制所有部分以减少问题的长度)。

xslt1:下面看到的,该问题是,空的命名空间的xmlns = “” 被添加到/文件的所有子节点(即:/ DOC/TAG1和/ DOC/TAG2)

<xsl:template match="/doc"> 
    <xsl:element name="{local-name()}" namespace="urn:test" > 
     <xsl:copy-of select="attribute::*"/> 
     <xsl:apply-templates select="@*|node()" /> 
    </xsl:element> 
</xsl:template> 

Xslt2 :见下文,问题是,“NS”被添加到根节点:和

<xsl:template match="/*"> 
    <xsl:element name="ns:{local-name()}" namespace="urn:test"> 
     <xsl:apply-templates select="node()|@*" /> 
    </xsl:element> 
</xsl:template> 

xslt3:下面看到的,问题是,错误报告:未定义命名空间前缀“瓮”。 XPST0081:表达式中使用的名称空间前缀必须使用静态已知名称空间可扩展到名称空间URI中。

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:attribute name="xmlns"> 
     <xsl:value-of select="urn:test" /> 
     </xsl:attribute> 
    <xsl:copy-of select="@*" /> 
    <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 

我只想用xmlns =“urn:test”与根节点/ doc进行简单的输出。

任何帮助,将不胜感激!

回答

2

我想的属性(命名空间)添加到根元素

命名空间声明是的属性。而这里所要求的改变并不单单是根元素:在根中声明的命名空间是由它的所有后代继承的。这意味着你需要移动所有元素融入到新的命名空间:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

</xsl:stylesheet> 
+0

迈克尔,感谢您的回答。您提供的xslt与我的第一个xslt具有相同的输出。我真的不想在所有子节点上都有“xmlns =”“”。有没有办法使用第二个xslt在子节点上删除它? – dellair

+0

@dellair我的XSLT的输出在所有子节点上都没有“xmlns =”“” - 请参阅:http://xsltransform.net/pPzifq3 –

+0

这绝对是我的错。我刚刚编辑了这个问题,并复制了完整的xml。您可以看到“xmlns =”“”已被添加到具有完整xml的子节点中。 – dellair