如何用XSLT 1.0为XML元素设置新命名空间前缀实现目标输出
XSLT 1.0 命名空间前缀转换修正方案
问题根源
输出出现多余原XML结构,本质是XSLT默认模板的递归复制逻辑在起作用——XSLT 1.0的默认模板会自动处理所有未被显式匹配的节点,导致原结构被意外保留。此外需确保命名空间前缀与目标节点的绑定完全符合要求。
修正实现
1. 声明命名空间映射
在XSLT根节点中明确绑定两个命名空间的前缀,同时排除不需要输出的xsl前缀:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tp="http://your-tp-namespace-uri" xmlns:header="http://your-header-namespace-uri" exclude-result-prefixes="xsl">
替换示例中的URI为你实际使用的命名空间地址。
2. 覆盖默认模板
禁用默认的节点复制行为,只处理我们显式匹配的节点:
<!-- 覆盖默认模板,仅转发处理逻辑,不复制未匹配节点 --> <xsl:template match="*|@*|text()|comment()|processing-instruction()"> <xsl:apply-templates/> </xsl:template>
3. 编写节点匹配模板
前两个节点绑定tp前缀
假设输入的前两个节点为Root和Request,模板如下:
<xsl:template match="/Root"> <tp:Root> <xsl:apply-templates select="Request"/> </tp:Root> </xsl:template> <xsl:template match="Request"> <tp:Request> <xsl:apply-templates select="Message"/> </tp:Request> </xsl:template>
Message及其子节点绑定header前缀
通过动态元素生成批量处理子节点,无需逐个编写模板:
<xsl:template match="Message"> <header:Message> <xsl:apply-templates select="@*|node()"/> </header:Message> </xsl:template> <!-- 为Message下所有子节点添加header前缀 --> <xsl:template match="Message/*"> <xsl:element name="header:{local-name()}"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template>
完整示例
输入XML
<Root> <Request> <Message> <MsgID>REQ-001</MsgID> <Timestamp>2024-05-20</Timestamp> </Message> </Request> </Root>
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tp="http://your-tp-namespace-uri" xmlns:header="http://your-header-namespace-uri" exclude-result-prefixes="xsl"> <!-- 禁用默认节点复制 --> <xsl:template match="*|@*|text()|comment()|processing-instruction()"> <xsl:apply-templates/> </xsl:template> <xsl:template match="/Root"> <tp:Root> <xsl:apply-templates select="Request"/> </tp:Root> </xsl:template> <xsl:template match="Request"> <tp:Request> <xsl:apply-templates select="Message"/> </tp:Request> </xsl:template> <xsl:template match="Message"> <header:Message> <xsl:apply-templates select="@*|node()"/> </header:Message> </xsl:template> <xsl:template match="Message/*"> <xsl:element name="header:{local-name()}"> <xsl:apply-templates select="@*|node()"/> </xsl:element> </xsl:template> </xsl:stylesheet>
输出结果
<tp:Root xmlns:tp="http://your-tp-namespace-uri" xmlns:header="http://your-header-namespace-uri"> <tp:Request> <header:Message> <header:MsgID>REQ-001</header:MsgID> <header:Timestamp>2024-05-20</header:Timestamp> </header:Message> </tp:Request> </tp:Root>
关键提示
- 所有需要保留的节点必须有显式模板匹配,否则会被默认模板跳过
- 使用
xsl:element的动态命名语法可以高效处理同一父节点下的所有子节点,避免重复编写模板 - 命名空间URI是节点匹配的核心,前缀仅为别名,需确保与目标XML的URI完全一致
内容的提问来源于stack exchange,提问作者Shashiraj Noorithaya
相关产品推荐
相关产品推荐

