07-07-2025, 07:33 PM
Introduction
This blog will show you how to create a single interface in SAP CPI that can be reused for processing proxy XML data from SAP S4/SAP systems or any other systems also.
Use Case
We will come across situations where we need to send different sets of data with different XML structures from SAP or SAP S4 to a target application using SAP CPI.
Normally, we design a specific proxy structure for XML that the ABAP team can use to send data to the middleware. But when there are multiple XML structures and the data needs to be sent separately from the source system, we often need to create multiple proxy structures. Also, if a field name needs to be changed or a new field needs to be added, the interface must be updated each time.
I came across this situation where SAP needed to send different XML messages, and the ABAP team asked for multiple proxy structures and changes. Each different message was going to the same target application but with a different resource path. This is going to take lot of time and different interfaces are needed as each message use different path in the HTTP.
To avoid this, I used a standardized XML format with simple <FieldName> and <FieldValue> pairs, and I added a resource path identifier in the header. This way, I was able to create just one reusable interface in SAP CPI that could handle all the different incoming messages, which I then sent to the target application.
Architecture
ProcessFlowDiagram.svg
Development Steps
RameshVaranganti_0-1750348469253.png
Standardize Input XML in SAP
I have created Standardize SAP proxy structures into a common, uniform format with header
<FieldName> and <FieldValue> XML pair structure
RameshVaranganti_1-1750348505072.png
This contains Header section I will be using to identify my resource path
In SAP CPI , I have used content modifier to capture the proxy header table data and saved it in property to use in HTTP receiver adapter. This property dynamically call the endpoint.
RameshVaranganti_2-1750348562227.png
Groovy Script in CPI for XML to Json
This Groovy script parses the incoming XML, extracts field-value pairs, and builds a JSON structure:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.*
import groovy.json.*
def Message processData(Message message)
{
def xml = message.getBody(java.lang.String)
def records = new XmlSlurper().parseText(xml)
def jsonList = records.Record.collect { record ->
def map = [:]
record.Item.each { item ->
map[item.FieldName.text()] = item.FieldValue.text()
}
return map
}
def json = JsonOutput.prettyPrint(JsonOutput.toJson(jsonList))
message.setBody(json)
return message;
}
Post Transformed JSON Data to Target Endpoint
HTTP Adapter configuration: In previous Content Modifier I have used Tablename to dynamically identify target URL.
RameshVaranganti_3-1750348605531.png
Testing
Input XML1
<Header>
<TableName>KLAH</TableName>
<Plant>001</Plant>
</Header>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>CLINT</FieldName>
<FieldValue>1234</FieldValue>
</Item>
<Item>
<FieldName>KLART</FieldName>
<FieldValue>003</FieldValue>
</Item>
</Record>
Output Json1:
[
{
"MANDT": "300",
"CLINT": "1234",
"KLART": "003"
}
]
example2:
Input XML
<message>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>TPLNR</FieldName>
<FieldValue>001A</FieldValue>
</Item>
<Item>
<FieldName>SPRAS</FieldName>
<FieldValue>E</FieldValue>
</Item>
<Item>
<FieldName>PLTXT</FieldName>
<FieldValue>CheckPLTXTValueRecord1</FieldValue>
</Item>
<Item>
<FieldName>PLTXU</FieldName>
<FieldValue>CheckPLTXUTValueRec1</FieldValue>
</Item>
</Record>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>TPLNR</FieldName>
<FieldValue>001B</FieldValue>
</Item>
<Item>
<FieldName>SPRAS</FieldName>
<FieldValue>E</FieldValue>
</Item>
<Item>
<FieldName>PLTXT</FieldName>
<FieldValue>CheckPLTXTValueRecord2</FieldValue>
</Item>
<Item>
<FieldName>PLTXU</FieldName>
<FieldValue>CheckPLTXUTValueRec2</FieldValue>
</Item>
</Record>
</message>
OutputJson:
[
{
"MANDT": "300",
"TPLNR": "001A",
"SPRAS": "E",
"PLTXT": "CheckPLTXTValueRecord1",
"PLTXU": "CheckPLTXUTValueRec1"
},
{
"MANDT": "300",
"TPLNR": "001B",
"SPRAS": "E",
"PLTXT": "CheckPLTXTValueRecord2",
"PLTXU": "CheckPLTXUTValueRec2"
}
]
Take Away
This design reusable, scalable integration strategy in SAP CPI using Groovy scripting and a generalized XML structure for simple transmissions.
Implementing a single interface capable of handling multiple tables data with dynamic fields, this solution simplifies integration architecture, accelerates delivery, and reduces ongoing maintenance.
Finally it eliminates the need of create multiple interfaces for similar data transmissions if we could able to handle simple design approcahes in SAP CPI.
This blog will show you how to create a single interface in SAP CPI that can be reused for processing proxy XML data from SAP S4/SAP systems or any other systems also.
Use Case
We will come across situations where we need to send different sets of data with different XML structures from SAP or SAP S4 to a target application using SAP CPI.
Normally, we design a specific proxy structure for XML that the ABAP team can use to send data to the middleware. But when there are multiple XML structures and the data needs to be sent separately from the source system, we often need to create multiple proxy structures. Also, if a field name needs to be changed or a new field needs to be added, the interface must be updated each time.
I came across this situation where SAP needed to send different XML messages, and the ABAP team asked for multiple proxy structures and changes. Each different message was going to the same target application but with a different resource path. This is going to take lot of time and different interfaces are needed as each message use different path in the HTTP.
To avoid this, I used a standardized XML format with simple <FieldName> and <FieldValue> pairs, and I added a resource path identifier in the header. This way, I was able to create just one reusable interface in SAP CPI that could handle all the different incoming messages, which I then sent to the target application.
Architecture
ProcessFlowDiagram.svg
Development Steps
RameshVaranganti_0-1750348469253.png
Standardize Input XML in SAP
I have created Standardize SAP proxy structures into a common, uniform format with header
<FieldName> and <FieldValue> XML pair structure
RameshVaranganti_1-1750348505072.png
This contains Header section I will be using to identify my resource path
In SAP CPI , I have used content modifier to capture the proxy header table data and saved it in property to use in HTTP receiver adapter. This property dynamically call the endpoint.
RameshVaranganti_2-1750348562227.png
Groovy Script in CPI for XML to Json
This Groovy script parses the incoming XML, extracts field-value pairs, and builds a JSON structure:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.*
import groovy.json.*
def Message processData(Message message)
{
def xml = message.getBody(java.lang.String)
def records = new XmlSlurper().parseText(xml)
def jsonList = records.Record.collect { record ->
def map = [:]
record.Item.each { item ->
map[item.FieldName.text()] = item.FieldValue.text()
}
return map
}
def json = JsonOutput.prettyPrint(JsonOutput.toJson(jsonList))
message.setBody(json)
return message;
}
Post Transformed JSON Data to Target Endpoint
HTTP Adapter configuration: In previous Content Modifier I have used Tablename to dynamically identify target URL.
RameshVaranganti_3-1750348605531.png
Testing
Input XML1
<Header>
<TableName>KLAH</TableName>
<Plant>001</Plant>
</Header>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>CLINT</FieldName>
<FieldValue>1234</FieldValue>
</Item>
<Item>
<FieldName>KLART</FieldName>
<FieldValue>003</FieldValue>
</Item>
</Record>
Output Json1:
[
{
"MANDT": "300",
"CLINT": "1234",
"KLART": "003"
}
]
example2:
Input XML
<message>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>TPLNR</FieldName>
<FieldValue>001A</FieldValue>
</Item>
<Item>
<FieldName>SPRAS</FieldName>
<FieldValue>E</FieldValue>
</Item>
<Item>
<FieldName>PLTXT</FieldName>
<FieldValue>CheckPLTXTValueRecord1</FieldValue>
</Item>
<Item>
<FieldName>PLTXU</FieldName>
<FieldValue>CheckPLTXUTValueRec1</FieldValue>
</Item>
</Record>
<Record>
<Item>
<FieldName>MANDT</FieldName>
<FieldValue>300</FieldValue>
</Item>
<Item>
<FieldName>TPLNR</FieldName>
<FieldValue>001B</FieldValue>
</Item>
<Item>
<FieldName>SPRAS</FieldName>
<FieldValue>E</FieldValue>
</Item>
<Item>
<FieldName>PLTXT</FieldName>
<FieldValue>CheckPLTXTValueRecord2</FieldValue>
</Item>
<Item>
<FieldName>PLTXU</FieldName>
<FieldValue>CheckPLTXUTValueRec2</FieldValue>
</Item>
</Record>
</message>
OutputJson:
[
{
"MANDT": "300",
"TPLNR": "001A",
"SPRAS": "E",
"PLTXT": "CheckPLTXTValueRecord1",
"PLTXU": "CheckPLTXUTValueRec1"
},
{
"MANDT": "300",
"TPLNR": "001B",
"SPRAS": "E",
"PLTXT": "CheckPLTXTValueRecord2",
"PLTXU": "CheckPLTXUTValueRec2"
}
]
Take Away
This design reusable, scalable integration strategy in SAP CPI using Groovy scripting and a generalized XML structure for simple transmissions.
Implementing a single interface capable of handling multiple tables data with dynamic fields, this solution simplifies integration architecture, accelerates delivery, and reduces ongoing maintenance.
Finally it eliminates the need of create multiple interfaces for similar data transmissions if we could able to handle simple design approcahes in SAP CPI.