Recent project required to use groovy scripted mapping, using StreamingMarkupBuilder to produce output XML, then post to Odata services.
Below is the skeleton content in groovy script. With this script, can act as alternative to graphical mapping, and use groovy/java language to read source xml, extract value, put in variable, and output to target xml using template, in a very clean, easy readable, procedural programming way.
This is comparable to SAX parsing method in Java Mapping, but in a cleaner syntax, concise, not so verbose like pure Java XML manipulation.
You can run the script in any external java/groovy editor. Example IntelliJ IDEA. The function TestRun() act as a mock test receive input from file, and output to file.
import java.util.HashMap;
import groovy.util.*
import groovy.xml.*
import com.sap.gateway.ip.core.customdev.util.Message;
def Message processData(Message message) {
//Body
def body = message.getBody();
def headers = message.getHeaders();
def properties = message.getProperties();
message.setBody(BuildOutput(body))
return message;
}
//TestRun()
def String TestRun(){
def input = new File('C:\\Your_Path\\Sample_Data\\Z_IDOC.txt').getText('UTF-8')
def output = XmlUtil.serialize(BuildOutput(input))
File file = new File('C:\\Your_Path\\Sample_Data\\Z_IDOC_OUTPUT.txt')
file.write output
}
def String BuildOutput(String input, String V_SAP_ApplicationID) {
def Z_IDOC = new XmlSlurper().parseText(input)
def writer = new StringWriter()
def builder = new StreamingMarkupBuilder()
// MAPPING
def SomeEntity_MARKUP = {
mkp.xmlDeclaration()
batchParts {
batchChangeSet {
Z_IDOC.IDOC.each { this_IDOC ->
def V_DOCNUM = this_IDOC.EDI_DC40.DOCNUM
def V_SNDPRN = this_IDOC.EDI_DC40.SNDPRN
def V_CREDAT = this_IDOC.EDI_DC40.CREDAT
def V_CRETIM = this_IDOC.EDI_DC40.CRETIM
def V_SERIAL = this_IDOC.EDI_DC40.SERIAL
def V_VAR1 = this_IDOC.SUB1.SUB2.SUB3.VAR1
def V_VAR2 = this_IDOC.SUB1.SUB2.SUB3.VAR2
def V_VAR3 = this_IDOC.SUB5.SUB6.VAR3
def V_VAR4 = this_IDOC.SUB7.SUB8.SUB9.VAR4
OutputRoot {
method('POST')
headers {
header {
headerName('RequestTimestamp')
headerValue("$V_CREDAT$V_CRETIM")
}
header {
headerName('SequenceNumber')
headerValue("$V_SERIAL")
}
header {
headerName('IdocNumber')
headerValue("$V_DOCNUM")
}
}
SomeEntity {
EntityRecord {
VAR1("$V_VAR1")
VAR2("$V_VAR2")
VAR3("$V_VAR3")
VAR4("$V_VAR4")
}
}
}
}
}
}
}
// WRITING
writer << builder.bind(SomeEntity_MARKUP)
def output = writer.toString()
return output
}
to try, idoc sample is needed (Z_IDOC.txt)
could you post it?
Thanks
Rudi
hi, those Z_IDOC.txt is mock up idoc based on real idoc for illustrate the concept, so not really have sample data. You can use any idoc xml you have, and just change the idoc path according to get the values in your idoc.