如何在XSLT中动态生成命名空间的XML属性?例如,我们可以使用不同的属性来使用以下XML文档,例如attr1:foo
或attr2:bar
:
<a xmlns="http://example.com/"
xmlns:attr1="http://example.com/attr1#"
xmlns:attr2="http://example.com/attr2#">
<b attr1:foo=""/>
<b attr2:bar=""/>
</a>
假设我们想要转换文档并将所有属性的值更改为...
。我们应该如何构建这些属性?如何解决这个问题的一个自然选择是使用<xsl:attribute>
。但是我们应该将QName用作name
属性?函数name()
可以将属性的QName作为字符串返回。 NaïveXSL模板可能如下所示:
<xsl:template match="@*">
<xsl:attribute name="{name()}">...</xsl:attribute>
</xsl:template>
但是,由于name()
将QName作为字符串返回,因此此解决方案需要通过XSLT中的xmlns
预定义命名空间前缀绑定(例如,xmlns:attr1="http://example.com/attr1#"
)。
然后我想知道使用namespace
的{{1}}属性是否可行:
<xsl:attribute>
这个解决方案似乎有效,但我认为这在XSLT中几乎不是最佳实践。你知道更好的解决方案吗?
答案 0 :(得分:2)
这取决于您对源文档结构的了解:
如果您知道使用的命名空间及其前缀绑定,那么 在样式表中声明它们并使用你所谓的“天真的XSL” 模板”。
否则,请复制命名空间(URI),如第二个模板中所示。
另请注意,您可以将两者合并如下:
<xsl:template match="@*">
<xsl:attribute name="{name()}" namespace="{namespace-uri()}">...</xsl:attribute>
</xsl:template>
对于某些处理器(例如Saxon 6.5),这将确保在结果中重复使用原始前缀;其他处理器(例如libxslt和Xalan)无论如何都会这样做。