XSLT:如何编写冗余xmlns?

时间:2010-12-24 06:55:08

标签: xslt

我需要为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而忽略父级?

1 个答案:

答案 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:textdisable-output-escaping直接生成所需的XML,如下所示:

<xsl:template match="/">
  <xsl:text disable-output-escaping="yes">&lt;root xmlns="http://something"&gt;</xsl:text>
  <xsl:text disable-output-escaping="yes">&lt;node xmlns="http://something"&gt;</xsl:text>
  <xsl:text disable-output-escaping="yes">&lt;/root&gt;</xsl:text>
</xsl:template>

请注意,XSLT 1.0规范在序列化方面非常宽松,因此特定的XSLT处理器仍然可以设想从第二个解决方案中剥离冗余的命名空间声明。但是,它在我尝试的四个处理器中工作(即Saxon,MSXML,MSXML.NET和LIBXML)。