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

请求开发XSLT实现基于序列的跨XML文件数据转换

跨XML文件的XSLT序列转换解决方案

问题说明

需基于两个XML文件(filea.xml、fileb.xml)实现数据转换,核心需求:

  • 按映射规则将filea中的数字型siteid/partNum替换为fileb中对应位置的实际值
  • 按站点分组部件数据,并对部件排序
  • 生成指定结构的目标XML

映射规则

  1. filea.xml中siteid的数字值对应fileb.xml中<sites>元素的位置序号:
    • siteid=1 → 第1个<sites>值:RSA00083
    • siteid=2 → 第2个<sites>值:RSA00034
  2. filea.xml中partNum的数字值对应fileb.xml中<partnumber>元素的位置序号:
    • partNum=1 → 第1个<partnumber>值:000B96
    • partNum=2 → 第2个<partnumber>值:000B97

源文件(修正语法错误后)

filea.xml

<Json>
  <site_req>
    <siteid>1</siteid>
    <quantityAvail>1</quantityAvail>
    <quantityMax>1</quantityMax>
    <partNum>1</partNum>
    <partRequested>1</partRequested>
  </site_req>
  <site_req>
    <siteid>1</siteid>
    <quantityAvail>2</quantityAvail>
    <quantityMax>2</quantityMax>
    <partNum>2</partNum>
    <partRequested>2</partRequested>
  </site_req>
  <site_req>
    <siteid>2</siteid>
    <quantityAvail>3</quantityAvail>
    <quantityMax>31</quantityMax>
    <partNum>2</partNum>
    <partRequested>3</partRequested>
  </site_req>
</Json>

注:修正了原文件中标签闭合错误(</FMI_INQUIRE_REQ>改为</site_req>、<partRequested<2改为<partRequested>2)

fileb.xml

<?xml version="1.0" encoding="UTF-8"?>
<Json xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <method>inquire</method>
  <params>
    <control>
      <origin>Oracle</origin>
      <version>12.0</version>
    </control>
    <inquiry>
      <sites>RSA00083</sites>
      <sites>RSA00034</sites>
      <sites>RSA00033</sites>
      <parts>
        <partnumber>000B96</partnumber>
        <partnumberAssigner>TATA</partnumberAssigner>
        <partnumber>000B97</partnumber>
        <partnumberAssigner>TATA</partnumberAssigner>
      </parts>
    </inquiry>
  </params>
</Json>

目标文件

<?xml version="1.0" encoding="utf-8"?>
<result xsi:noNamespaceSchemaLocation="schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <siteList>
    <siteid>RSA00083</siteid>
    <partsList>
      <partnum>000B96</partnum>
      <partAssigner>TATA</partAssigner>
      <sequenceNumber>1</sequenceNumber>
      <quantityAvail>1</quantityAvail>
      <quantityMax>1</quantityMax>
    </partsList>
    <partsList>
      <partnum>000B97</partnum>
      <partAssigner>TATA</partAssigner>
      <sequenceNumber>2</sequenceNumber>
      <quantityAvail>2</quantityAvail>
      <quantityMax>2</quantityMax>
    </partsList>
  </siteList>
  <siteList>
    <siteid>RSA00034</siteid>
    <partsList>
      <partnum>000B97</partnum>
      <partAssigner>TATA</partAssigner>
      <sequenceNumber>3</sequenceNumber>
      <quantityAvail>3</quantityAvail>
      <quantityMax>31</quantityMax>
    </partsList>
  </siteList>
  <messages>
    <messageType>INFO</messageType>
    <messageCode>TATA001</messageCode>
    <messageVars/>
    <fieldName />
    <app>Oracle Inventory</app>
    <module>Inv</module>
    <messageText>Information Received.</messageText>
  </messages>
</result>

注:修正了目标文件中<siteId>标签大小写不一致问题,统一为<siteid>


原代码问题分析

你编写的XSLT仅做了简单的标签复制/改名,未实现:

  1. 跨文件读取fileb.xml的映射数据
  2. siteid/partNum与实际值的映射逻辑
  3. 按站点分组、部件排序的核心需求
  4. 目标XML的结构生成

解决XSLT代码(XSLT 1.0)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 定义键:按实际站点ID分组site_req -->
  <xsl:key name="site-group" match="site_req" use="document('fileb.xml')//sites[position() = current()/siteid]"/>

  <!-- 主模板:生成根元素result -->
  <xsl:template match="/">
    <result xsi:noNamespaceSchemaLocation="schema.xsd">
      <!-- 遍历所有唯一的站点分组 -->
      <xsl:for-each select="Json/site_req[generate-id() = generate-id(key('site-group', document('fileb.xml')//sites[position() = siteid])[1])]">
        <xsl:variable name="current-site-id" select="document('fileb.xml')//sites[position() = siteid]"/>
        <siteList>
          <siteid><xsl:value-of select="$current-site-id"/></siteid>
          <!-- 对当前站点下的部件请求按partRequested排序 -->
          <xsl:for-each select="key('site-group', $current-site-id)">
            <xsl:sort select="partRequested" data-type="number"/>
            <partsList>
              <!-- 映射partNum到实际部件编号 -->
              <xsl:if test="partNum">
                <xsl:variable name="part-index" select="partNum"/>
                <partnum><xsl:value-of select="document('fileb.xml')//partnumber[$part-index]"/></partnum>
                <partAssigner><xsl:value-of select="document('fileb.xml')//partnumberAssigner[$part-index]"/></partAssigner>
              </xsl:if>
              <sequenceNumber><xsl:value-of select="partRequested"/></sequenceNumber>
              <quantityAvail><xsl:value-of select="quantityAvail"/></quantityAvail>
              <quantityMax><xsl:value-of select="quantityMax"/></quantityMax>
            </partsList>
          </xsl:for-each>
        </siteList>
      </xsl:for-each>
      <!-- 固定messages部分 -->
      <messages>
        <messageType>INFO</messageType>
        <messageCode>TATA001</messageCode>
        <messageVars/>
        <fieldName />
        <app>Oracle Inventory</app>
        <module>Inv</module>
        <messageText>Information Received.</messageText>
      </messages>
    </result>
  </xsl:template>

  <!-- 忽略默认节点复制 -->
  <xsl:template match="@*|node()"/>
</xsl:stylesheet>

关键逻辑说明

  1. 跨文件读取:使用document('fileb.xml')加载外部XML文件,通过位置索引position()实现数字到实际值的映射
  2. 站点分组:用<xsl:key>定义分组规则,按映射后的实际站点ID对site_req分组
  3. 排序处理:对每个站点下的site_req按partRequested数值排序
  4. 结构生成:直接构建目标XML的层级结构,包含映射后的站点、部件信息,以及固定的messages模块

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:40:57