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

如何基于条件在XSLT中包装节点?优化现有实现方案

优化XSLT条件包裹节点的代码(消除重复)

需求

当city节点的name属性值为Venezia时,将生成的CityName节点包裹在myCity元素内;其他情况直接输出CityName节点。目前已实现功能,但CityName的代码存在重复,需要更简洁的实现方式(除了创建模板调用外的方案)。

输入XML

<cities>
    <city name="Milano"/>
    <city name="Paris"/>
    <city name="Munchen"/>
    <city name="Lyon"/>
    <city name="Venezia"/>
</cities>

现有XSLT(存在代码重复)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="city">
        <xsl:choose>
            <xsl:when test="@name='Venezia'">
                <myCity>
                    <CityName>
                        <xsl:value-of select="@name"/>
                    </CityName>
                </myCity>
            </xsl:when>
            <xsl:otherwise>
                <CityName>
                    <xsl:value-of select="@name"/>
                </CityName>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <!-- Identity Transform-->
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*"/>
</xsl:stylesheet>

期望输出

<cities>
    <CityName>Milano</CityName>
    <CityName>Paris</CityName>
    <CityName>Munchen</CityName>
    <CityName>Lyon</CityName>
    <myCity>
        <CityName>Venezia</CityName>
    </myCity>
</cities>

优化方案(利用模板匹配优先级,无代码重复)

通过拆分两个匹配模板消除重复,利用XSLT中更具体的模板匹配优先级更高的特性,完全避免代码冗余:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <!-- 匹配name为Venezia的city节点,输出带myCity包裹的结构 -->
    <xsl:template match="city[@name='Venezia']">
        <myCity>
            <CityName>
                <xsl:value-of select="@name"/>
            </CityName>
        </myCity>
    </xsl:template>

    <!-- 匹配其他所有city节点,直接输出CityName -->
    <xsl:template match="city">
        <CityName>
            <xsl:value-of select="@name"/>
        </CityName>
    </xsl:template>
    
    <!-- 身份转换模板 -->
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*"/>
</xsl:stylesheet>

补充:单模板内的紧凑写法(若接受命名模板)

如果不想拆分模板,也可以提取重复逻辑为命名模板,减少代码重复:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="city">
        <xsl:choose>
            <xsl:when test="@name='Venezia'">
                <myCity>
                    <xsl:call-template name="city-name"/>
                </myCity>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="city-name"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="city-name">
        <CityName>
            <xsl:value-of select="@name"/>
        </CityName>
    </xsl:template>
    
    <!-- 身份转换模板 -->
    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*"/>
</xsl:stylesheet>

注:第一种拆分匹配模板的方案更贴合需求,无需额外模板调用,完全依赖XSLT自身的匹配机制实现条件区分,逻辑清晰且无冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:25:29