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

XSLT统计xsl:for-each内xsl:choose执行次数及无匹配输出默认值

XSLT匹配提取及默认值实现问题

我需要提取所有匹配的ttype和vendor.id,匹配规则为:assemblyCustom/revisionCustom/entityTypeCode 和 assemblyCustom/revisionCustom/usCode 分别与任意 ttypes-config/item/enityTypeCode/ 和 ttypes-config/item/usCode 的值匹配。

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<combined-xml>
    <assemblyCustom>
        <revisionCustom>
            <entityTypeCode>C</entityTypeCode>
            <usCode>G</usCode>
        </revisionCustom>
    </assemblyCustom>
    <ttypes-config>
        <item>
            <vendor.id>111</vendor.id>
            <ttype>AAA</ttype>
            <enityTypeCode>
                <item>C</item>
                <item>D</item>
                <item>E</item>
                <item>F</item>
            </enityTypeCode>
            <usCode>
                <item>G</item>
                <item>H</item>
                <item>I</item>
                <item>J</item>
                <item>K</item>
                <item>L</item>
                <item>M</item>
            </usCode>
        </item>
        <item>
            <vendor.id>222</vendor.id>
            <ttype>BBB</ttype>
            <enityTypeCode>
                <item>N</item>
                <item>C</item>
            </enityTypeCode>
            <usCode>
                <item>G</item>
            </usCode>
        </item>
        <item>
            <vendor.id>333</vendor.id>
            <ttype>CCC</ttype>
            <enityTypeCode>
                <item>Q</item>
                <item>R</item>
            </enityTypeCode>
            <usCode>
                <item>S</item>
            </usCode>
        </item>
        <item>
            <vendor.id>444</vendor.id>
            <ttype>DDD</ttype>
            <enityTypeCode>
                <item>T</item>
                <item>U</item>
            </enityTypeCode>
            <usCode>
                <item>V</item>
            </usCode>
        </item>
        
        <item>
            <vendor.id>555</vendor.id>
            <ttype>EEEs</ttype>
            <enityTypeCode>
                <item>W</item>
                </enityTypeCode>
            <usCode>
                <item>X</item>
                <item>Y</item>
            </usCode>
        </item>
    </ttypes-config>
</combined-xml>

期望输出

匹配成功时

<?xml version="1.0" encoding="UTF-8"?>
<ttype-output>
    <ttype>AAA</ttype>
    <vendor.id>111</vendor.id>
    <ttype>BBB</ttype>
    <vendor.id>222</vendor.id>
   
</ttype-output>

无匹配时

<?xml version="1.0" encoding="UTF-8"?>
<ttype-output>
    <ttype>Default</ttype>
    <vendor.id>000</vendor.id>
</ttype-output>

当前已实现的XSL代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:variable name="entityTypeCode">
        <xsl:value-of select="combined-xml/assemblyCustom/revisionCustom/entityTypeCode"/>
    </xsl:variable>
    <xsl:variable name="usCode">
        <xsl:value-of select="combined-xml/assemblyCustom/revisionCustom/usCode"/>
    </xsl:variable>

    <xsl:template match="/combined-xml/ttypes-config/item">
        <xsl:variable name="current_entityTypeCode">
            <xsl:value-of select="enityTypeCode"/>
        </xsl:variable>
        <xsl:variable name="current_usCode">
            <xsl:value-of select="usCode"/>
        </xsl:variable>
        <xsl:if test="contains($current_entityTypeCode, $entityTypeCode) and contains($current_usCode, $usCode)">
            <ttype>
                <xsl:value-of select="ttype"/>
            </ttype>
            <vendor.id>
                <xsl:value-of select="vendor.id"/>
            </vendor.id>
        </xsl:if>

    </xsl:template>
    <xsl:template match="/">
        <ttype-output>
            <xsl:apply-templates select="/combined-xml/ttypes-config/item"></xsl:apply-templates>
        </ttype-output>
    </xsl:template>

</xsl:stylesheet>

待解决的问题

  1. 如何统计xsl:for-each语句内xsl:choose的执行次数?
  2. 如何添加xsl:otherwise逻辑,实现只有当所有循环迭代都不满足条件时才输出默认ttype?

解决方案

先修正现有匹配逻辑的问题

你当前用contains()判断存在逻辑漏洞:如果enityTypeCode/item存在值为CA的项,匹配C时也会被误命中。建议直接判断是否存在相等的子项,匹配条件修改为:

<xsl:if test="enityTypeCode/item[text()=$entityTypeCode] and usCode/item[text()=$usCode]">

问题1:统计xsl:for-each内xsl:choose的执行次数

XSLT是函数式语言,变量赋值后不可变,你可以通过以下方式统计:

  • 如果是XSLT 2.0及以上版本,直接统计符合条件的节点数即可:
    <xsl:variable name="matchCount" select="count(/combined-xml/ttypes-config/item[enityTypeCode/item/text()=$entityTypeCode and usCode/item/text()=$usCode])"/>
    
  • 如果是XSLT 1.0,也可以先把匹配到的节点存入节点集变量,再统计数量:
    <xsl:variable name="matchedItems" select="/combined-xml/ttypes-config/item[enityTypeCode/item/text()=$entityTypeCode and usCode/item/text()=$usCode]"/>
    <xsl:variable name="matchCount" select="count($matchedItems)"/>
    

你所说的xsl:choose执行次数本质就是循环的item总数,直接用count(/combined-xml/ttypes-config/item)就能获取。

问题2:实现无匹配时输出默认值

你可以先把匹配到的内容存入变量,判断匹配数量是否为0,再输出默认值即可。以下是修改后的完整XSL代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:variable name="entityTypeCode" select="combined-xml/assemblyCustom/revisionCustom/entityTypeCode"/>
    <xsl:variable name="usCode" select="combined-xml/assemblyCustom/revisionCustom/usCode"/>
    <!-- 先筛选所有匹配的item -->
    <xsl:variable name="matchedItems" select="/combined-xml/ttypes-config/item[enityTypeCode/item/text()=$entityTypeCode and usCode/item/text()=$usCode]"/>

    <xsl:template match="item" mode="output">
        <ttype>
            <xsl:value-of select="ttype"/>
        </ttype>
        <vendor.id>
            <xsl:value-of select="vendor.id"/>
        </vendor.id>
    </xsl:template>

    <xsl:template match="/">
        <ttype-output>
            <xsl:choose>
                <!-- 有匹配项时输出所有匹配结果 -->
                <xsl:when test="$matchedItems">
                    <xsl:apply-templates select="$matchedItems" mode="output"/>
                </xsl:when>
                <!-- 无匹配时输出默认值 -->
                <xsl:otherwise>
                    <ttype>Default</ttype>
                    <vendor.id>000</vendor.id>
                </xsl:otherwise>
            </xsl:choose>
        </ttype-output>
    </xsl:template>

</xsl:stylesheet>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 19:45:01