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

如何在XSLT 2.0中不使用for-each循环合并两个XML输入变量

问题描述

需要处理InputVar1.xml中的每个<employeeNumber>,从InputVar2.xml中获取对应的部门信息,生成指定格式的输出文件,仅保留InputVar1中存在的员工记录。要求使用XSLT 2.0实现,且不得使用for-each循环。

输入文件

InputVar1.xml

<Employees>
    <List>
        <employeeNumber>123</employeeNumber>
        <employeeName>abc</employeeName>
    </List>
    <List>
        <employeeNumber>453</employeeNumber>
        <employeeName>cde</employeeName>
    </List>
    <List>
        <employeeNumber>678</employeeNumber>
        <employeeName>efg</employeeName>
    </List>
</Employees>

注:原输入存在标签拼写错误(emplyeeNumber、emploeeName),上述代码已修正为正确拼写,若需匹配原错误标签,可自行替换对应名称

InputVar2.xml

<Departs>
   <List>
     <employeeNumber>123</employeeNumber>
     <departName>fin</departName>
     <departId>10</departId>
   </List>
   <List>
     <employeeNumber>919</employeeNumber>
     <departName>adm</departName>
     <departId>20</departId>
   </List>
   <List>
     <employeeNumber>453</employeeNumber>
     <departName>hr</departName>
     <departId>30</departId>
   </List>
</Departs>

期望输出

<WriteFile>
  <LinesRecordSet>
    <LinesRecord>
      <employeeNumber>123</employeeNumber>
      <departName>fin</departName>
      <departId>10</departId>
      <employeeName>abc</employeeName>
    </LinesRecord>
    <LinesRecord>
      <employeeNumber>453</employeeNumber>
      <departName>hr</departName>
      <departId>30</departId>
      <employeeName>cde</employeeName>
    </LinesRecord>
    <LinesRecord>
      <employeeNumber>678</employeeNumber>
      <departName></departName>
      <departId></departId>
      <employeeName>efg</employeeName>
    </LinesRecord>
  </LinesRecordSet>
</WriteFile>

XSLT 2.0 解决方案

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义键,以员工编号为索引关联部门信息 -->
    <xsl:key name="dept-by-empnum" match="Departs/List" use="employeeNumber"/>

    <!-- 处理InputVar1的根节点 -->
    <xsl:template match="/Employees">
        <WriteFile>
            <LinesRecordSet>
                <!-- 应用模板处理所有员工节点,替代for-each循环 -->
                <xsl:apply-templates select="List"/>
            </LinesRecordSet>
        </WriteFile>
    </xsl:template>

    <!-- 处理单个员工节点 -->
    <xsl:template match="List">
        <LinesRecord>
            <!-- 复制员工编号 -->
            <xsl:copy-of select="employeeNumber"/>
            <!-- 获取部门名称,无匹配则为空 -->
            <departName>
                <xsl:value-of select="key('dept-by-empnum', employeeNumber)/departName"/>
            </departName>
            <!-- 获取部门ID,无匹配则为空 -->
            <departId>
                <xsl:value-of select="key('dept-by-empnum', employeeNumber)/departId"/>
            </departId>
            <!-- 复制员工姓名 -->
            <xsl:copy-of select="employeeName"/>
        </LinesRecord>
    </xsl:template>

    <!-- 忽略无关文本节点 -->
    <xsl:template match="text()"/>
</xsl:stylesheet>

核心说明

  • 键索引优化:通过<xsl:key>建立员工编号与部门信息的映射,避免遍历整个部门列表,提升匹配效率。
  • 模板驱动替代循环:使用<xsl:apply-templates>触发模板匹配,自动处理每个员工节点,完全规避for-each的使用。
  • 空值兼容:当员工无对应部门记录时,value-of返回空字符串,自动生成空的部门元素,符合输出要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:05:13