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

能否使用key()配合xsl:key简化存在重复判断的XSLT代码?

XSLT代码简化方案

你需要的核心是把重复的面额存在性判断逻辑抽离,避免重复编写,这里提供两种常用实现方案,优先推荐更直观的预筛选变量方案,也同时提供你提到的<xsl:key>实现思路。

方案1:预筛选有效货币节点(最简洁,推荐)

直接一次性把所有符合条件的currency节点筛选出来存为节点集变量,后续所有操作都直接使用这个已经过滤好的节点序列即可,判断逻辑仅需要写1次:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:variable name="test">
        <root>
            <other1>
            </other1>
            <currency g="1">
                <sth1>A</sth1>
                <thousand>1</thousand>
                <hundred>2</hundred>
                <fifty>4</fifty>
                <one>10</one>
                <sth2>C</sth2>
            </currency>
            <currency g="2">
                <sth1>A</sth1>
                <sth2>C</sth2>
            </currency>
            <currency g="3">
                <sth1>A</sth1>
                <thousand>1</thousand>
                <hundred>2</hundred>
                <fifty>4</fifty>
                <one>10</one>
                <sth2>C</sth2>
            </currency>
            <other2>
            </other2>
        </root>
    </xsl:variable>
    <xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="curr" select="xalan:nodeset($test)/root"/>
    <!-- 新增:一次性筛选所有有效货币节点,判断逻辑仅写1次 -->
    <xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="validCurrencies" select="$curr/currency[thousand or hundred or fifty or one]"/>
    
    <xsl:template match="/">
        <root>
            <xsl:call-template name="currency"/>
        </root>
    </xsl:template>
    
    <xsl:template name="currency">
        <!-- 直接遍历预筛选的有效节点 -->
        <xsl:for-each select="$validCurrencies">
            <xsl:if test="position() mod 3 = 1">
                <!-- 直接在有效节点序列里取对应位置的后续节点,无需额外判断 -->
                <xsl:variable name="pos" select="position()"/>
                <xsl:variable name="nextSibling1" select="$validCurrencies[$pos + 1]"/>
                <xsl:variable name="nextSibling2" select="$validCurrencies[$pos + 2]"/>
                <col1>
                    <xsl:apply-templates select="." mode="total"/>
                </col1>
                 <col2>
                     <xsl:apply-templates select="$nextSibling1" mode="total"/>
                 </col2>
                 <col3>
                     <xsl:apply-templates select="$nextSibling2" mode="total"/>
                 </col3>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match="currency" mode="total">
        <xsl:value-of select="thousand*1000 + hundred*100 + fifty*50 + one"/>
    </xsl:template>
    
    <xsl:template match="*"/>
</xsl:stylesheet>

运行结果和原代码完全一致:

<root>
<col1>1410</col1>
<col2>1410</col2>
<col3/>
</root>

方案2:使用<xsl:key>实现(符合你提到的思路)

如果你偏好使用key实现,可以按如下方式定义和使用:

<!-- 定义key,匹配有效currency节点,用g属性作为索引 -->
<xsl:key name="validCurrency" match="currency[thousand or hundred or fifty or one]" use="@g"/>

使用时直接通过key('validCurrency', @g)即可判断当前currency是否有效,也可直接通过key('validCurrency', /*)获取所有有效节点。不过对于这个场景,方案1的预筛选变量写法更简洁易懂,维护成本更低。

内容的提问来源于stack exchange,提问作者Guasqueño

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:54:01