如何使用XSLT为XML节点的所有子节点添加前缀并重命名?
解决方案
你可以通过一个通用模板实现动态给子节点添加前缀,不用为Telefon和Fax分别写重复逻辑。核心思路是利用父节点名称生成新的子节点标签名,结合concat()和lower-case()函数完成前缀拼接。
以下是完整的XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 基础复制模板:复制所有未被特殊匹配的节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 移除Telefon和Fax的外层标签,直接处理子节点 --> <xsl:template match="Telefon | Fax"> <xsl:apply-templates select="@*|node()"/> </xsl:template> <!-- 为Telefon/Fax的子节点添加对应前缀 --> <xsl:template match="Telefon/* | Fax/*"> <!-- 拼接新标签名:父节点小写名称 + "-" + 当前节点名称 --> <xsl:element name="{concat(lower-case(local-name(parent::*)), '-', local-name())}"> <!-- 复制当前节点的属性和内容 --> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
代码说明
- 基础复制模板:这是XSLT常用的「身份模板」,负责复制所有未被其他模板匹配的节点和属性,确保不需要修改的内容保持原样。
- 移除外层标签模板:匹配
Telefon和Fax元素,不复制它们本身,直接将处理逻辑传递给子节点,从而去掉外层的<Telefon>和<Fax>标签。 - 动态生成前缀模板:匹配
Telefon或Fax的所有子节点:- 用
local-name(parent::*)获取父节点名称,再通过lower-case()转为小写,确保前缀是telefon-或fax-; - 用
concat()把小写父节点名、-和当前节点名称拼接成新标签名(比如telefon-area、fax-number); - 最后复制当前节点的属性和内部内容,保证数据不丢失。
- 用
把这段XSLT应用到你的输入XML上,就能得到你想要的输出结构。
内容的提问来源于stack exchange,提问作者Dénes Ákos Nagy
相关产品推荐
相关产品推荐

