1

我有一个 XSLT 样式表,它需要发出一个看起来像这样的 XML 片段(为简洁起见,省略了“...”位):

<MyOuterType xmlns:xsi="..." xsi:type="foo:MyInnerType" xmlns:foo="..."/>

样式表如下所示:

<xsl:stylesheet xmlns:foo="..." xmlns:xsi="...">
  ...
  <xsl:template match="...">
    <xsl:element name="MyOuterType">
      <xsl:attribute name="xsi:type">foo:MyInnerType</xsl:attribute>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

XSLT 处理器的输出如下所示:

<MyOuterType xmlns:xsi="..." xsi:type="foo:MyInnerType"/>

换句话说,它缺少xmlns:foo声明。事实上,尽管在样式表中声明了声明,但发出的 XML 中完全没有声明。当我需要反序列化发出的 XML 时,这会搞砸事情。

如何让我xmlns:foo出现在发出的 XML 中?处理器实现 XSLT 1.0。

4

1 回答 1

0

这取决于您是否知道要静态生成的命名空间,或者它是否基于输入文档中的信息。

如果您静态地知道它,只需使用文字结果元素而不是 xsl:element:

<MyOuterType xsi:type="foo:MyInnerType" xmlns:foo="....."/>

如果这是一个动态的决定,那就有点复杂了。XSLT 2.0 有一个 xsl:namespace 指令来生成名称空间,其方式与 xsl:attribute 生成属性的方式非常相似。在 XSLT 1.0 中,诀窍是创建一个包含所需命名空间的元素,然后使用 xsl:copy 复制命名空间节点:

<xsl:variable name="dummy">
  <xsl:element name="foo:dummy" namespace="{$param}"/>
</xsl:variable>
<MyOuterType xsi:type="foo:MyInnerType">
  <xsl:copy-of select="exsl:node-set($dummy)/*/namespace::foo"/>
</MyOuterType>

不幸的是,有一两个不完全 XSLT-1.0 处理器没有正确实现命名空间节点,所以要小心。

于 2012-10-23T20:45:01.490 回答