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

请求编写XSLT实现按学生分组拆分XML数据

问题:将连续节点按学生信息分组包裹为节点

现有一份XML数据,<root>下的<item>节点按顺序每3个为一组,对应一名学生的StudentID、StudentName、City信息。需要编写XSLT,将每组三个<item>节点包裹到<Record>节点中输出。

输入XML

<?xml version="1.0" encoding="UTF-8" ?>
<root>
    <item>
        <columnName>StudentID</columnName>
        <value>2356</value>
    </item>
    <item>
        <columnName>StudentName</columnName>
        <value>Java</value>
    </item>
    <item>
        <columnName>City</columnName>
        <value>Chicago</value>
    </item>
    <item>
        <columnName>StudentID</columnName>
        <value>4578</value>
    </item>
    <item>
        <columnName>StudentName</columnName>
        <value>Net</value>
    </item>
    <item>
        <columnName>City</columnName>
        <value>NewYork</value>
    </item>
    <item>
        <columnName>StudentID</columnName>
        <value>5892</value>
    </item>
    <item>
        <columnName>StudentName</columnName>
        <value>Office</value>
    </item>
    <item>
        <columnName>City</columnName>
        <value>Dallas</value>
    </item>
</root>

期望输出XML

<?xml version="1.0" encoding="UTF-8" ?>
<root>
    <Record>
        <item>
            <columnName>StudentID</columnName>
            <value>2356</value>
        </item>
        <item>
            <columnName>StudentName</columnName>
            <value>Java</value>
        </item>
        <item>
            <columnName>City</columnName>
            <value>Chicago</value>
        </item>
    </Record>
    <Record>
        <item>
            <columnName>StudentID</columnName>
            <value>4578</value>
        </item>
        <item>
            <columnName>StudentName</columnName>
            <value>Net</value>
        </item>
        <item>
            <columnName>City</columnName>
            <value>NewYork</value>
        </item>
    </Record>
    <Record>
        <item>
            <columnName>StudentID</columnName>
            <value>5892</value>
        </item>
        <item>
            <columnName>StudentName</columnName>
            <value>Office</value>
        </item>
        <item>
            <columnName>City</columnName>
            <value>Dallas</value>
        </item>
    </Record>
</root>

现有未完成XSLT代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>
    <xsl:template match="root">
        <root>
            <Record>
                <xsl:apply-templates select="data"/>
            </Record>
            <Record/>
        </root>
    </xsl:template>
    <xsl:template match="data">
        <data>
            <xsl:apply-templates select="columnName"/>
            <xsl:apply-templates select="value"/>
        </data>
    </xsl:template>
    <xsl:template match="columnName">
        <columnName>
            <xsl:value-of select="."/>
        </columnName>
    </xsl:template>
    <xsl:template match="value">
        <value>
            <xsl:value-of select="."/>
        </value>
    </xsl:template>
</xsl:stylesheet>

正确XSLT实现方案

以下是可以实现需求的XSLT代码:

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

    <!-- 处理根节点,遍历每个学生的起始item(StudentID) -->
    <xsl:template match="root">
        <root>
            <xsl:apply-templates select="item[columnName='StudentID']" mode="record"/>
        </root>
    </xsl:template>

    <!-- 为每个学生生成Record节点,包含当前item及后续两个兄弟item -->
    <xsl:template match="item" mode="record">
        <Record>
            <xsl:copy-of select="."/>
            <xsl:copy-of select="following-sibling::item[1]"/>
            <xsl:copy-of select="following-sibling::item[2]"/>
        </Record>
    </xsl:template>

    <!-- 屏蔽默认文本节点处理,避免输出多余空白 -->
    <xsl:template match="text()"/>
</xsl:stylesheet>

实现思路

  1. 定位分组起始点:选择所有columnName为StudentID的<item>节点,这些节点是每个学生信息的第一个节点。
  2. 生成Record节点:对每个起始<item>,生成<Record>节点,并复制当前节点以及后面两个兄弟<item>,刚好组成一个学生的完整信息。
  3. 清理多余内容:添加空模板匹配文本节点,防止XML中的空白字符被错误输出。

如果不想依赖columnName的值,也可以通过节点位置来分组,将<xsl:apply-templates>的选择器改为item[position() mod 3 = 1],这样每3个<item>为一组,取第一个作为起始点,效果相同。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:45:41