我有一个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。
答案 0 :(得分: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处理器没有正确实现命名空间节点,所以请谨慎。