无需为每个元素建模板,移除m:命名空间复制<mathml>子元素的XSLT方案
当然有可行的解决方案!你不需要为每个<m:*>元素单独写模板,只需要用通用的XSLT规则就能批量移除命名空间前缀,同时保留MathML的命名空间声明。
完整XSLT实现
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML"> <!-- 身份模板:默认复制所有节点、属性和文本 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配所有m命名空间下的元素,移除前缀并保留命名空间 --> <xsl:template match="m:*"> <!-- 创建无前缀的元素,继承原MathML命名空间 --> <xsl:element name="{local-name()}" namespace="http://www.w3.org/1998/Math/MathML"> <!-- 复制所有属性 --> <xsl:apply-templates select="@*"/> <!-- 递归处理子节点 --> <xsl:apply-templates select="node()"/> </xsl:element> </xsl:template> <!-- 可选:如果需要移除外层的<mathml>容器,添加这个模板 --> <xsl:template match="mathml"> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
代码解释
- 身份模板:作为基础规则,会默认复制所有未被其他模板匹配的节点(包括文本、属性、注释等),保证非MathML内容不受影响。
- m命名空间元素模板:专门匹配所有
m:前缀的元素,用local-name()获取元素的本地名称(去掉前缀),同时显式指定MathML的命名空间,这样输出的元素就没有前缀但仍属于正确的MathML命名空间。 - 可选的mathml容器模板:如果你的需求是只保留内部的MathML内容(如预期输出那样去掉外层
<mathml>),就加上这个模板,它会直接处理<mathml>的子节点而不复制自身。
输入输出验证
输入示例
<mathml> <m:math xmlns:m="http://www.w3.org/1998/Math/MathML"> <m:mrow> <m:mtext>SL depreciation expense</m:mtext> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mtext>cost−residual value</m:mtext> </m:mrow> <m:mrow> <m:mtext>useful life</m:mtext> </m:mrow> </m:mfrac> </m:mrow> </m:math> </mathml>
输出结果
<math xmlns="http://www.w3.org/1998/Math/MathML"> <mrow> <mtext>SL depreciation expense</mtext> <mo>=</mo> <mfrac> <mrow> <mtext>cost−residual value</mtext> </mrow> <mrow> <mtext>useful life</mtext> </mrow> </mfrac> </mrow> </math>
这个方案完全满足你的需求:批量处理所有子元素、移除m:前缀,且无需为每个元素单独编写模板。
内容的提问来源于stack exchange,提问作者Hasitha Ediriweera
相关产品推荐
相关产品推荐

