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

SAP CPI:使用Groovy在指定XML节点后追加节点失败求助

SAP CPI Groovy脚本节点插入问题解决方法

问题说明

在SAP CPI中尝试通过Groovy脚本,将包含SenderBusinessSystemID和RecipientBusinessSystemID的<MessageHeader>节点插入到XML的<BusinessPartnerSUITEBulkReplicateRequest>节点内部、第一个<BusinessPartnerSUITEReplicateRequestMessage>节点之前,但操作失败。直接将节点追加到消息末尾可正常执行,尝试通过命名空间定位目标节点也未成功。

原始XML

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <ns1:BusinessPartnerSUITEBulkReplicateRequest xmlns:ns1="http://sap.com/xi/SAPGlobal20/Global">
         <BusinessPartnerSUITEReplicateRequestMessage>
            <BusinessPartner actionCode="04" addressInformationListCompleteTransmissionIndicator="true" roleListCompleteTransmissionIndicator="true">
               <UUID>b26a8b91-da4d-4761-bbc5-4bf704f0eb4a</UUID>
               <InternalID>00000016</InternalID>
               <CategoryCode>2</CategoryCode>
               <AddressInformation actionCode="04">
                  <UUID>3ccc411f-5ff3-4f78-a38a-11c4eb45d30c</UUID>
                  <Address actionCode="04" emailListCompleteTransmissionIndicator="true" facsimileListCompleteTransmissionIndicator="true">
                     <CommunicationPreference actionCode="04">
                        <CorrespondenceLanguageCode>DE</CorrespondenceLanguageCode>
                     </CommunicationPreference>
                     <Email actionCode="04" eMailUsageListCompleteTransmissionIndicator="true">
                        <URI>test@sap.com</URI>
                        <UsageDeniedIndicator>false</UsageDeniedIndicator>
                        <EmailUsage actionCode="04">
                           <Usage>
                              <Code>AD_DEFAULT</Code>
                           </Usage>
                           <DefaultIndicator>true</DefaultIndicator>
                        </EmailUsage>
                     </Email>
                     <PostalAddress actionCode="04">
                        <CountryCode>UA</CountryCode>
                        <RegionCode />
                        <CityName>Bönen</CityName>
                        <StreetPostalCode>59199</StreetPostalCode>
                        <StreetName>Siemensstraße</StreetName>
                        <HouseID>10</HouseID>
                        <POBoxID />
                     </PostalAddress>
                  </Address>
               </AddressInformation>
               <Common actionCode="04">
                  <Organisation>
                     <Name>
                        <FirstLineName>testfirstname</FirstLineName>
                        <SecondLineName>testlastname</SecondLineName>
                     </Name>
                  </Organisation>
               </Common>
               <Role actionCode="04">
                  <RoleCode>ZCU005</RoleCode>
               </Role>
            </BusinessPartner>
         </BusinessPartnerSUITEReplicateRequestMessage>
         <BusinessPartnerSUITEReplicateRequestMessage>
            <BusinessPartner actionCode="04" addressInformationListCompleteTransmissionIndicator="true" commonListCompleteTransmissionIndicator="true" roleListCompleteTransmissionIndicator="true">
               <UUID>ace66c2d-44a8-4238-b411-53ad2520d7b4</UUID>
               <InternalID>DUMMY</InternalID>
               <CategoryCode>1</CategoryCode>
               <AddressInformation actionCode="04">
                  <UUID>eb16d063-faf5-4fbb-a67c-514216ee162f</UUID>
                  <Address actionCode="04" emailListCompleteTransmissionIndicator="true" facsimileListCompleteTransmissionIndicator="true">
                     <CommunicationPreference actionCode="04">
                        <CorrespondenceLanguageCode>DE</CorrespondenceLanguageCode>
                     </CommunicationPreference>
                     <PersonName actionCode="04">
                        <Name>
                           <GivenName>DUMMYfirstname</GivenName>
                           <FamilyName>DUMMYlastname</FamilyName>
                        </Name>
                     </PersonName>
                  </Address>
               </AddressInformation>
               <Role actionCode="04">
                  <RoleCode>BUP001</RoleCode>
               </Role>
            </BusinessPartner>
         </BusinessPartnerSUITEReplicateRequestMessage>
      </ns1:BusinessPartnerSUITEBulkReplicateRequest>
   </ns0:Message1>
</ns0:Messages>

目标追加节点

<MessageHeader>
  <SenderBusinessSystemID>${sender}</SenderBusinessSystemID>
  <RecipientBusinessSystemID>${receiver}</RecipientBusinessSystemID>
</MessageHeader>

当前Groovy脚本

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;


def Message processData(Message message) {
    
    def ns0 = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge');
    def ns1 = new groovy.xml.Namespace('http://sap.com/xi/SAPGlobal20/Global');
    def receiver = message.getProperties().get("Receiver");
    def sender = message.getProperties().get("Sender");
    def body = message.getBody(java.lang.String) as String;
    def newString = "<MessageHeader><SenderBusinessSystemID>"+sender+"</SenderBusinessSystemID><RecipientBusinessSystemID>"+receiver+"</RecipientBusinessSystemID></MessageHeader>"

    def response= new XmlSlurper().parseText(body)
    def newNode = new XmlSlurper().parseText(newString)     
    
response.Messages[0].Message1[0].BusinessPartnerSUITEBulkReplicateRequest[0].appendNode(newNode);
response.appendNode(newNode);
def String outxml = groovy.xml.XmlUtil.serialize(response)
    
  message.setBody(outxml);       
 
  return message;
}

解决思路及修正脚本

问题分析

  1. 命名空间未正确使用:BusinessPartnerSUITEBulkReplicateRequest属于ns1命名空间,直接通过节点名访问无法定位到目标节点,必须结合命名空间进行查找。
  2. 插入位置错误:appendNode方法是将节点追加到目标节点的子节点末尾,而需求是插入到第一个BusinessPartnerSUITEReplicateRequestMessage之前,需要使用insertBefore方法。
  3. 节点创建方式优化:使用MarkupBuilder创建新节点比解析字符串更可靠,避免潜在的XML格式问题。

修正后的Groovy脚本

import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.xml.XmlSlurper;
import groovy.xml.XmlUtil;
import groovy.xml.MarkupBuilder;
import java.io.StringWriter;

def Message processData(Message message) {
    // 定义命名空间
    def ns0 = new groovy.xml.Namespace('http://sap.com/xi/XI/SplitAndMerge');
    def ns1 = new groovy.xml.Namespace('http://sap.com/xi/SAPGlobal20/Global');
    
    // 获取Sender和Receiver属性
    def receiver = message.getProperties().get("Receiver");
    def sender = message.getProperties().get("Sender");
    
    // 解析原始XML
    def body = message.getBody(java.lang.String) as String;
    def xmlSlurper = new XmlSlurper(false, false);
    def response = xmlSlurper.parseText(body);
    
    // 使用MarkupBuilder创建MessageHeader节点
    def writer = new StringWriter();
    def markupBuilder = new MarkupBuilder(writer);
    markupBuilder.MessageHeader {
        SenderBusinessSystemID(sender)
        RecipientBusinessSystemID(receiver)
    }
    def newNode = new XmlSlurper().parseText(writer.toString());
    
    // 定位目标父节点:BusinessPartnerSUITEBulkReplicateRequest
    def bulkRequestNode = response[ns0.Message1][ns1.BusinessPartnerSUITEBulkReplicateRequest][0];
    
    // 定位第一个要插入的位置节点:BusinessPartnerSUITEReplicateRequestMessage
    def firstRequestMessageNode = bulkRequestNode.BusinessPartnerSUITEReplicateRequestMessage[0];
    
    // 在第一个RequestMessage节点前插入新节点
    firstRequestMessageNode.insertBefore(newNode);
    
    // 序列化XML并设置回消息体
    def outxml = XmlUtil.serialize(response);
    message.setBody(outxml);       
    
    return message;
}

关键点说明

  • 命名空间定位:通过response[ns0.Message1][ns1.BusinessPartnerSUITEBulkReplicateRequest]正确定位到目标父节点,避免因命名空间缺失导致的节点查找失败。
  • 插入方法:使用insertBefore方法将新节点插入到指定节点的前面,满足需求中的位置要求。
  • 节点创建:MarkupBuilder更适合动态生成XML节点,减少字符串拼接可能带来的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:02:03