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

Groovy/XSLT实现可变User节点XML到SOAP结构的转换问询

如何将包含可变节点的源XML转换为指定SOAP格式的目标XML?

我最近碰到一个XML转换的需求,需要把一个带有数量可变<User>节点的源XML转换成指定结构的SOAP格式目标XML。我一开始尝试用字符串拼接来构建目标结构,但卡在了动态迭代<User>节点生成对应<object>节点的环节,想请教下有没有Groovy脚本或者XSLT的解决方案。

源XML结构

<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <User>
    <person>
      <person_id>1234</person_id>
    </person>
  </User>
  <User>
    <person>
      <person_id>5678</person_id>
    </person>
  </User>
</Response>

目标XML结构要求

<?xml version="1.0" encoding="UTF-8"?>
<S:Body xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <queryResponse xmlns="urn:test.com" xmlns:ns2="urn:example.com">
    <result>
      <object>
        <id>1234(*person_id from source message*)</id>
        <type>Employee</type>
        <person>*here the whole person number 1 object from source XML must be inserted*</person>
        <execution_timestamp></execution_timestamp>
        <version_id></version_id>
      </object>
      <object>
        <id>5678(*person_id from source message*)</id>
        <type>Employee</type>
        <person>*here the whole person number 2 object from source XML must be inserted*</person>
        <execution_timestamp></execution_timestamp>
        <version_id></version_id>
      </object>
      <numResults>*number of Users from source XML must be inserted here(in this case 2)*</numResults>
    </result>
  </queryResponse>
</S:Body>

核心需求

  • 每个源XML中的<User>节点对应目标XML里的一个<object>节点
  • <object>的<id>字段取对应<User>下的<person_id>值
  • <object>的<person>节点完整复制源XML中对应的<person>内容
  • <numResults>字段填充源XML中<User>节点的总数量

方案一:XSLT转换(推荐)

XSLT是专门为XML转换设计的工具,非常适配这类场景,下面是完整的转换样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns="urn:test.com"
                xmlns:ns2="urn:example.com">
    <!-- 输出配置:格式化XML,保留UTF-8编码 -->
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <!-- 匹配源XML的根节点<Response> -->
    <xsl:template match="/Response">
        <S:Body>
            <queryResponse>
                <result>
                    <!-- 遍历所有<User>节点,生成对应的<object> -->
                    <xsl:for-each select="User">
                        <object>
                            <!-- 提取person_id作为id值 -->
                            <id><xsl:value-of select="person/person_id"/></id>
                            <type>Employee</type>
                            <!-- 完整复制整个<person>节点 -->
                            <xsl:copy-of select="person"/>
                            <execution_timestamp/>
                            <version_id/>
                        </object>
                    </xsl:for-each>
                    <!-- 统计<User>节点的总数量 -->
                    <numResults><xsl:value-of select="count(User)"/></numResults>
                </result>
            </queryResponse>
        </S:Body>
    </xsl:template>
</xsl:stylesheet>

使用方式:你可以用任何支持XSLT 1.0的工具(比如Java的TransformerFactory、在线XML转换工具),将源XML和上述XSLT文件作为输入,即可生成符合要求的SOAP XML。


方案二:Groovy脚本实现

Groovy对XML的解析和生成非常便捷,借助XmlSlurper(解析源XML)和MarkupBuilder(生成目标XML)可以快速实现需求:

@Grab('org.codehaus.groovy:groovy-xml:3.0.17')
import groovy.xml.XmlSlurper
import groovy.xml.MarkupBuilder

// 读取源XML(可替换为文件读取:new File('source.xml').text)
def sourceXml = '''<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <User>
    <person>
      <person_id>1234</person_id>
    </person>
  </User>
  <User>
    <person>
      <person_id>5678</person_id>
    </person>
  </User>
</Response>'''

// 解析源XML
def response = new XmlSlurper().parseText(sourceXml)
def users = response.User

// 生成目标SOAP XML
def writer = new StringWriter()
def xmlBuilder = new MarkupBuilder(writer)
xmlBuilder.setDoubleQuotes(true)
xmlBuilder.mkp.xmlDeclaration(version: '1.0', encoding: 'UTF-8')

xmlBuilder.'S:Body'(xmlns:S: 'http://schemas.xmlsoap.org/soap/envelope/') {
    'queryResponse'(xmlns: 'urn:test.com', 'xmlns:ns2': 'urn:example.com') {
        result {
            // 遍历每个<User>生成对应的<object>
            users.each { user ->
                object {
                    id(user.person.person_id.text())
                    type('Employee')
                    // 完整复制<person>节点内容
                    mkp.yieldUnescaped(user.person.toString())
                    execution_timestamp()
                    version_id()
                }
            }
            // 填充<User>节点数量
            numResults(users.size())
        }
    }
}

// 输出转换后的XML
println writer.toString()

运行说明:直接执行该Groovy脚本,会在控制台输出符合要求的SOAP XML,你可以根据实际需求调整源XML的读取方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:55:39