如何用Groovy解析含迭代节点的XML并按规则提取Customer值
XML解析与Customer值提取需求及脚本优化
需求说明
需解析包含迭代OrderHeaderPartnerType节点的XML,按以下规则提取并存储Customer值:
- 校验
OrderHeaderPartnerType/PartnerFunction等于'SH'时,收集该节点下的Customer值; - 若该节点对应的
OrderHeaderPartnerType/Address/PartnerFunction不存在,则将收集到的Customer值存入属性。
XML输入示例
<Order> <OrderType> <CreationDate>2024-10-21T00:00:00.000</CreationDate> <Partner> <OrderHeaderPartnerType> <PartnerFunction>SP</PartnerFunction> <Customer>1000082984</Customer> <Address/> </OrderHeaderPartnerType> <OrderHeaderPartnerType> <PartnerFunction>SH</PartnerFunction> <Customer>1000082984</Customer> <Address> <OrderPartnerAddressType> <StreetName>Adresse: husplan 45/47</StreetName> <PartnerFunction>SH</PartnerFunction> </OrderPartnerAddressType> </Address> </OrderHeaderPartnerType> </Partner> </OrderType> </Order>
现有Groovy脚本
import com.sap.gateway.ip.core.customdev.util.Message; import java.util.HashMap; import groovy.util.XmlSlurper; import groovy.xml.XmlUtil; import groovy.json.*; def Message processData(Message message){ //read input XML message and stored in property def body = message.getBody(String); def data = new XmlSlurper().parseText(body) // set the input body to the parameter message.setBody(body) message.setProperty("p_readInput", body) // Identify OrderHeaderPartner PartnerFunction value is equal to 'SH' data.OrderType.Partner.OrderHeaderPartnerType.children().each{OrderHeaderPartnerType -> def OrdHdrPartnerFunctionValue = ${OrderHeaderPartnerType.PartnerFunction()} // collect SalesOrderHeaderPartner 'Customer' value def OrdHdrPartnerFunctionCustomerValue = ${OrderHeaderPartnerType.Customer()} if (OrdHdrPartnerFunctionValue == SH) { // Identify OrderHeaderPartner Address PartnerFunction value exists in order to know whole address details are exists' data.OrderType.Partner.OrderHeaderPartnerType.Address.OrderPartnerAddressType.children().each{ addtag -> def HdrPartnerFunction_AddressValue = ${addtag.PartnerFunction()} if (HdrPartnerFunction_AddressValue == null) { message.setProperty("p_HdrPartnerFunctionCustomerValue",OrdHdrPartnerFunctionCustomerValue) } }}} return message }
现有脚本问题说明
- 语法错误:获取节点值时错误使用
${}包裹,Groovy中直接调用text()方法即可;字符串SH未加引号,会被识别为未定义变量。 - 逻辑错误:遍历Address节点时,错误遍历了所有
OrderHeaderPartnerType的Address,而非当前匹配的节点;判断节点是否存在的逻辑不准确,应该检查当前节点下的Address子节点是否包含PartnerFunction。
修正后的Groovy脚本
import com.sap.gateway.ip.core.customdev.util.Message; import groovy.util.XmlSlurper; def Message processData(Message message) { // 读取输入XML并保存到属性 def body = message.getBody(String); def data = new XmlSlurper().parseText(body); // 保留原始输入XML作为消息体 message.setBody(body); message.setProperty("p_readInput", body); // 遍历所有OrderHeaderPartnerType节点 data.OrderType.Partner.OrderHeaderPartnerType.each { partnerNode -> def partnerFunc = partnerNode.PartnerFunction.text().trim(); // 校验PartnerFunction为SH if (partnerFunc == 'SH') { def customerValue = partnerNode.Customer.text().trim(); // 检查当前节点下的Address是否存在PartnerFunction def addressPartnerFunc = partnerNode.Address.OrderPartnerAddressType.PartnerFunction.text().trim(); // 若Address下的PartnerFunction不存在(为空),则存入属性 if (!addressPartnerFunc) { message.setProperty("p_HdrPartnerFunctionCustomerValue", customerValue); } } } return message; }
预期输出
- 消息体保留原始输入XML内容;
- 当满足规则时,符合条件的
OrderHeaderPartnerType/Customer值会被存入属性p_HdrPartnerFunctionCustomerValue; - 针对示例XML,由于SH节点的Address下存在PartnerFunction,因此不会触发属性赋值;若SH节点的Address为空或无PartnerFunction,则对应的Customer值会被存入属性。
内容的提问来源于stack exchange,提问作者Sateesh
相关产品推荐
相关产品推荐

