如何在XSLT中动态生成命名空间的XML属性?

时间:2015-01-15 16:31:41

标签: xslt xml-namespaces

如何在XSLT中动态生成命名空间的XML属性?例如,我们可以使用不同的属性来使用以下XML文档,例如attr1:fooattr2: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中几乎不是最佳实践。你知道更好的解决方案吗?

1 个答案:

答案 0 :(得分:2)

这取决于您对源文档结构的了解:

  • 如果您知道使用的命名空间及其前缀绑定,那么 在样式表中声明它们并使用你所谓的“天真的XSL” 模板”。

  • 否则,请复制命名空间(URI),如第二个模板中所示。


另请注意,您可以将两者合并如下:

<xsl:template match="@*">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">...</xsl:attribute>
</xsl:template>

对于某些处理器(例如Saxon 6.5),这将确保在结果中重复使用原始前缀;其他处理器(例如libxslt和Xalan)无论如何都会这样做。

相关问题