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

XSLT 1.0中基于键的考勤数据值比较问题求助

XSLT 1.0 出勤人数差异检查问题修正方案

问题背景

需用XSLT 1.0处理WebService返回的XML,检查高中班级近5天出勤人数是否存在差异,原代码出现编译错误,无法得到预期输出。

输入XML

<response>
    <school1>
        <class>
        <attendance><class>a</class><day>monday</day><count>20</count></attendance>
        <attendance><class>a</class><day>tuesday</day><count>20</count></attendance>
        <attendance><class>a</class><day>wednesday</day><count>20</count></attendance>
        <attendance><class>a</class><day>thursday</day><count>20</count></attendance>   
        <attendance><class>a</class><day>friday</day><count>20</count></attendance>
        <attendance><class>b</class><day>monday</day><count>20</count></attendance>
        <attendance><class>b</class><day>tuesday</day><count>20</count></attendance>
        <attendance><class>b</class><day>wednesday</day><count>12</count></attendance>
        <attendance><class>b</class><day>thursday</day><count>20</count></attendance> 
        <attendance><class>b</class><day>friday</day><count>20</count></attendance>
       <attendance><class>c</class><day>monday</day><count>22</count></attendance>
       <attendance><class>c</class><day>tuesday</day><count>23</count></attendance>
       <attendance><class>c</class><day>wednesday</day><count>12</count></attendance>
       <attendance><class>c</class><day>thursday</day><count>20</count></attendance>
       <attendance><class>c</class><day>friday</day><count>22</count></attendance>
        </class>
    </school1>
</response>

原错误XSLT代码

<xsl:stylesheet version="1.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:key name="test" match="attendance[class='a']" use="count"/>
    <xsl:key name="test2" match="attendance[class='a'][last()]" use="count"/>
    <xsl:key name="test3" match="attendance[class='b']" use="count"/>
    <xsl:key name="test4" match="attendance[class='b'][last()]" use="count"/>
    <xsl:key name="test5" match="attendance[class='c']" use="count"/>
    <xsl:key name="test6" match="attendance[class='c'][last()]" use="count"/>
    <xsl:template match="/">
        <xsl:for-each select="/response/school1/class/attendance">
            <xsl:choose>
                <xsl:when test="$test!=$test2">
                    <xsl:value-of select="Check class roll" />                
              </xsl:when>  
                <xsl:otherwise>
                    <xsl:value-of select="Perfect Attendance" />
                </xsl:otherwise>
                <xsl:when test ="$test3!=$test4">
                    <xsl:value-of select="Check class roll" />                
                </xsl:when>  
                <xsl:otherwise>
                    <xsl:value-of select="Perfect Attendance" />
                </xsl:otherwise>
                <xsl:when test ="$test5!=$test6">
                    <xsl:value-of select="Check class roll" />                
                </xsl:when>  
                <xsl:otherwise>
                    <xsl:value-of select="Perfect Attendance" />
                </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

原代码错误分析

  1. 键的使用错误:xsl:key定义后需通过key()函数调用,不能直接用$key名引用;且match="attendance[class='a'][last()]"中的last()是全局所有attendance节点的最后一个,不是班级分组内的最后一个,逻辑完全错误。
  2. xsl:choose语法错误:一个xsl:choose只能包含多个xsl:when和一个xsl:otherwise,原代码嵌套多个otherwise违反语法。
  3. 遍历逻辑错误:原for-each遍历所有attendance节点,需求是按班级分组处理,而非每个出勤记录单独处理。
  4. 字符串输出错误:<xsl:value-of select="Check class roll" />未用单引号包裹字符串,会被解析为节点选择,而非输出固定文本。

修正后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>
    
    <!-- 按班级名称分组 -->
    <xsl:key name="class-group" match="attendance" use="class"/>
    
    <xsl:template match="/">
        <!-- 遍历每个班级的唯一分组 -->
        <xsl:for-each select="/response/school1/class/attendance[generate-id() = generate-id(key('class-group', class)[1])]">
            <xsl:variable name="current-class" select="class"/>
            <!-- 获取当前班级所有出勤人数 -->
            <xsl:variable name="all-counts" select="key('class-group', $current-class)/count"/>
            
            <xsl:choose>
                <!-- 检查所有count是否与第一个count相同 -->
                <xsl:when test="$all-counts != $all-counts[1]">
                    <xsl:text>Check class roll</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>Perfect Attendance</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
            <!-- 添加换行符分隔每个班级结果 -->
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 分组逻辑:用key('class-group', class)按班级名称对attendance节点分组,通过generate-id()筛选出每个班级的唯一节点作为分组入口。
  2. 差异检查:对每个班级的所有count节点,判断是否存在与第一个count值不同的节点,若存在则输出提示,否则输出正常。
  3. 输出格式:设置output method="text",直接输出预期的文本结果,每个班级结果后添加换行符。

预期输出

Perfect Attendance
Check class roll
Check class roll

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:27:05