提问人:Norman Gray 提问时间:12/11/2020 更新时间:12/11/2020 访问量:95
如何控制 XSLT 输出中的命名空间前缀(特别是默认命名空间)?
How do I control namespace prefixes (specifically the default namespace) in XSLT output?
问:
在 XSLT 中,有什么方法可以控制输出元素中命名空间前缀的选择?
在我的特殊情况下,我实际上想转换如下所示的输入
<h:html xmlns:h='http://www.w3.org/1999/xhtml'
xmlns:m='http://www.w3.org/1998/Math/MathML'>
....
<h:p>Equation: <m:math>...</m:math></h:p>
到
<html xmlns='http://www.w3.org/1999/xhtml'>
....
<p>Equation: <math xmlns='http://www.w3.org/1998/Math/MathML'>...</math></p>
也就是说,身份转换只需更改命名空间前缀,以根据需要对 XHTML 和 MathML 元素使用默认命名空间。
这是纯 XML 工作流末尾的一个整理步骤。以上当然在XML术语中是等价的,因此在XHTML术语中也是等价的,但浏览器似乎并不总是知道这一点(在我不是很系统的测试中,Firefox管理上述两个,在将它们呈现为数学的意义上 - Firefox干得好! – Safari管理第二个但不是第一个,Chrome也不管理;我实际上是针对 EPUB 读者的,但对那里的 XHTML 解析器持悲观态度似乎是明智的)。尝试使用 XSLT 元素不会对输出产生任何影响。XHTML 兼容性指南没有提到命名空间,这令人惊讶。添加 doctype 声明,甚至是提示 application/xhtml+xml 的 hack,似乎对浏览器的行为没有任何影响。<output method='html'/>
<meta http-equiv=''...>
在 XSLT 1.0 规范中,我看不到任何控制这一点的内容。这里提到的命名空间别名正在解决一个不同的问题;在 XSLT 中使用默认命名空间不会提供任何似乎倾向于采用的提示。其他堆栈交换问题(例如这个或这个)似乎在很大程度上是对 XSLT 和命名空间的误解。我敢肯定,在我漫长的 XSLT 过去的某个时刻,我已经成功地实现了这一点,但即使我做到了,我也无法复活它。libxslt
我非常喜欢 XSLT 1.0 中的解决方案,因为我有可用的工具和经验,可以在 libxslt 和 (Saxon 是一件非常美妙的事情,但我不愿意为可能的许多连续转换支付 Java 启动成本)。当然,这可能是迫使我使用更高版本的原因,如果更高版本确实是唯一可以提供帮助的东西。xsltproc
从(不是很彻底)查看 XSLT 3 规范(例如第 11.1 节),我看不到任何明显解决这个问题的内容。
如果我吠错了树,或者如果已知 EPUB 处理器对命名空间始终更了解,因此我实际上解决了问题的错误部分,我也对这些信息持开放态度。
答:
您需要进行转型
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="namespace-uri()">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
为其余部分设置标识转换模板。
在 XSLT 1 中,您有点依赖 XSLT 处理器及其序列化程序的怜悯来获得所需的输出,但我认为对于上面的模板,即使在 1.0 世界中,您也可以期待一些一致性。
评论
<h:p xmlns:h='http://www.w3.org/1999/xhtml'>...</h:p>
评论