Skip to Content
Technical Articles
Author's profile photo Govardanam Venkatesan

CSV File to N IDocs in SAP Cloud Integration!

This blog post describes the case of  CSV File to N IDocs conversion in SAP CI and a strong case, when a specific set of rows identified by unique value in the CSV File are to be converted into  individual IDoc, it requires conversion of grouped rows(by unique value)  into  individual messages before conversion into IDoc XML.

Use Case:

To convert CSV to IDoc XML where CSV contains rows grouped by unique values.


CSV file sorted  and grouped by unique values.



Let us take a look at how the flow 2 is implemented in SAP CI.

 Step1:Convert Grouped Row Items into a Line

Groovy Script

import java.util.HashMap;
def Message processData(Message message) {

    def iteratorValue=1;
    def body = message.getBody(java.lang.String);
    def rows = body.split("\n");
    def rowlength = rows.length;
    def columnsize = 5;//define the columnsize based on CSV file 
    def separtedCSVMessages = new String[rowlength];
    StringBuilder finalMessage = new StringBuilder();
    def separateMessageIterator =0;
    def rowsColumnsArray = new String[rowlength][columnsize];
    for(int i=0;i<rowlength;i++)
        rowsColumnsArray[i] = rows[i].split(";") as String[];

        def uniqueIdentifier =   rowsColumnsArray[iteratorValue][0];
        separtedCSVMessages[separateMessageIterator]= (rowsColumnsArray[iteratorValue] as java.lang.String).trim();
        while(iteratorValue+1 <rowlength && rowsColumnsArray[iteratorValue+1][0].equals(uniqueIdentifier))  {
            iteratorValue =  iteratorValue +1;
            separtedCSVMessages[separateMessageIterator] = (separtedCSVMessages[separateMessageIterator] as String) +':'+(rowsColumnsArray[iteratorValue] as String);
            if(iteratorValue+1 == rowlength)

        try {
            def temporaryString = (separtedCSVMessages[separateMessageIterator] as String).replace('[', '').replace(']','').replaceAll('\\R','');
        } catch(Exception e){

        if(iteratorValue < rowlength) {
            iteratorValue = iteratorValue + 1;
            separateMessageIterator = separateMessageIterator + 1;

    return message;

After this step, rows with same unique value(say column1) are grouped into one string with “:” as delimiter. After all rows with same unique values(identifier)  are appended to StringBuilder, a line break is added.

Step 2:Convert Line to Message

Iterating Splitter

Parelle Processing was unchecked to Support the Transaction Handling for JMS .

Now, after this step, you have M messages, M is the distinct unique identifiers (distinct column 1 values). This message is of text format .

Step 3: Re-Structure the Msg for XML Conversion

Groovy Script

import groovy.util.XmlParser

def Message processData(Message message) {
    String body = message.getBody(String);
    def rows = body.split(":") as String[];
    StringBuilder finalMessage = new StringBuilder();
    for(int i=0;i<rows.length;i++){
    return message;


Step 4: Convert CSV to XML Message


Step 5: XML to IDocXML Map

This is a Message Map from XML to IDoc XML.


Now, let us take a look at payload and analyze the output at each stage to better understand

  1. Initial CSV File Data (; Delimited)
  2. Output After Step 1:
    Message1, R1C2, R1C3, R1C4, R1C5:Message1, R2C2, R2C3, R2C4, R2C5:Message1, R3C2, R3C3, R3C4, R3C5
    Message2, R4C2, R4C3, R4C4, R4C5:Message2, R5C2, R5C3, R5C4, R5C5
    Message3, R6C2, R6C3, R6C4, R6C5:Message3, R7C2, R7C3, R7C4, R7C5:Message3, R8C2, R8C3, R8C4, R8C5:Message3, R9C2, R9C3, R9C4, R9C5
    Message4, R10C2, R10C3, R10C4, R10C5
    Message5, R11C2, R11C3, R11C4, R11C5     
  3. Output After Step 2:

M messages where M is distinct column 1 values . In our case, we have 5 Distinct values, so we have 5 messages.

Let us take one of the messages here

Message1, R1C2, R1C3, R1C4, R1C5:Message1, R2C2, R2C3, R2C4, R2C5:Message1, R3C2, R3C3, R3C4, R3C5

4.Output After Step3 :

Message1, R1C2, R1C3, R1C4, R1C5
Message1, R2C2, R2C3, R2C4, R2C5
Message1, R3C2, R3C3, R3C4, R3C5

5. Output After  Step 4:

<?xml version='1.0' encoding='UTF-8'?><MT_XML><rs><r><C1>Message1</C1><C2> R1C2</C2><C3> R1C3</C3><C4> R1C4</C4><C5> R1C5</C5></r><r><C1>Message1</C1><C2> R2C2</C2><C3> R2C3</C3><C4> R2C4</C4><C5> R2C5</C5></r><r><C1>Message1</C1><C2> R3C2</C2><C3> R3C3</C3><C4> R3C4</C4><C5> R3C5</C5></r></rs></MT_XML>

Further ,above Xml can be easily converted to IDoc Xml. Final output for the flow 2 when we tested it is as below ;

5 IDoc XML Messages in receiver Jms queue.


Further, why Transaction handling is set ?

We have set the Transaction handling for the flow to guarantee that either the whole CSV file is converted and N IDoc XML Messages in JMS queue are created, in case where one of the IDoc Maps have issue, we don’t want to create any message in JMS queue, rather we correct the errors in CSV file for the whole file to be processed  in one go. This is one of the approaches, further, if you don’t set transaction handling, then individual message might be processed, based on  configuration for iterating splitter and you go correct the records for the error message and process them alone as CSV file again.

Thanks for reading 🙂

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.