You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让XSLT 2.0模板同时处理XML原生元素与动态生成元素?

解决XSLT 2.0中原生元素与动态生成元素共享转换流程的问题

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<document>
    <h2>General Introduction</h2>
    <h3>Project Overview</h3>
    <h3>Goals and Challenges</h3>
    <h2>Installation</h2>
    <h3>Initial Configuration</h3>
    <h4>Configuration File</h4>
    <h3>Deployment</h3>
    <h4>On a Local Server</h4>
    <h4>On a Remote Server</h4>
    <h2>Usage</h2>
    <h3>Basic Commands</h3>
    <h3>Advanced Options</h3>
</document>

现有XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/document">
        <html>
            <body>
                <xsl:apply-templates/>
                <h3>Dynamic title (was not in the XML)</h3>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="h2 | h3 | h4">
        <xsl:element name="{name()}">
            ¶<xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

问题描述

转换对原始XML中的<h2>、<h3>和<h4>元素生效,但直接在XSLT中输出的动态<h3>元素未被匹配h2 | h3 | h4的模板处理,无法添加前缀。

解决方案

直接输出的<h3>是写入结果树的节点,不会触发模板匹配——模板默认只作用于源XML文档的节点或显式指定的节点树。以下两种方法可实现统一转换:

方案一:对动态构造的节点树应用模板

先将动态元素构造为节点变量,再用<xsl:apply-templates>处理该变量内的节点,触发匹配模板:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/document">
        <html>
            <body>
                <xsl:apply-templates/>
                <!-- 构造动态节点并应用模板 -->
                <xsl:variable name="dynamic-heading">
                    <h3>Dynamic title (was not in the XML)</h3>
                </xsl:variable>
                <xsl:apply-templates select="$dynamic-heading/h3"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="h2 | h3 | h4">
        <xsl:element name="{name()}">
            ¶<xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

方案二:抽离转换逻辑为命名模板

把标题的转换逻辑封装成命名模板,原生元素和动态元素统一调用该模板,避免重复代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/document">
        <html>
            <body>
                <xsl:apply-templates/>
                <!-- 调用命名模板处理动态标题 -->
                <xsl:call-template name="process-heading">
                    <xsl:with-param name="heading-name" select="'h3'"/>
                    <xsl:with-param name="heading-text" select="'Dynamic title (was not in the XML)'"/>
                </xsl:call-template>
            </body>
        </html>
    </xsl:template>

    <!-- 原生标题元素的模板,转发到命名模板 -->
    <xsl:template match="h2 | h3 | h4">
        <xsl:call-template name="process-heading">
            <xsl:with-param name="heading-name" select="name()"/>
            <xsl:with-param name="heading-text" select="."/>
        </xsl:call-template>
    </xsl:template>

    <!-- 通用标题处理逻辑 -->
    <xsl:template name="process-heading">
        <xsl:param name="heading-name"/>
        <xsl:param name="heading-text"/>
        <xsl:element name="{$heading-name}">
            ¶<xsl:value-of select="$heading-text"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

效果验证

两种方案都能让动态生成的<h3>元素与原生标题元素一致,添加前缀,实现统一的转换效果。

内容的提问来源于stack exchange,提问作者fauve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 09:11:00