我需要为bizzare系统提供以下输出,它需要在父级和子级中声明相同的xmlns,否则拒绝工作。那就是预期的结果:
<root xmlns="http://something">
<element xmlns="http://something" />
</root>
我可以使用
在root中创建xmlns<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:element name="root" namespace="http://something">
<xsl:element name="node" namespace="http://something" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但是它没有将xmlns添加到childnode中,因为节点的父节点具有相同的xmlns。如何强制XSLT编写xmlns而忽略父级?
答案 0 :(得分:0)
名为xmlns
的XML架构规范expressly prohibits属性,因此直接使用<xsl:attribute>
的XSLT样式表cannot create such attributes。我只能看到两个选项...
一种选择是使用不同的名称(例如xmlnsx
)创建虚拟属性:
<xsl:template match="/">
<xsl:element name="root">
<xsl:attribute name="xmlnsx">http://something</xsl:attribute>
<xsl:element name="node">
<xsl:attribute name="xmlnsx">http://something</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:template>
...然后在某些后处理步骤(例如SAX过滤器或其他流编辑器)中将所有出现的属性xmlnsx
替换为xmlns
。但是,此解决方案涉及将非XSLT步骤插入管道中。
另一种选择是纯粹的,如果丑陋的话,XSLT。您可以使用xsl:text
和disable-output-escaping
直接生成所需的XML,如下所示:
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><root xmlns="http://something"></xsl:text>
<xsl:text disable-output-escaping="yes"><node xmlns="http://something"></xsl:text>
<xsl:text disable-output-escaping="yes"></root></xsl:text>
</xsl:template>
请注意,XSLT 1.0规范在序列化方面非常宽松,因此特定的XSLT处理器仍然可以设想从第二个解决方案中剥离冗余的命名空间声明。但是,它在我尝试的四个处理器中工作(即Saxon,MSXML,MSXML.NET和LIBXML)。