Skip to Content
Author's profile photo Sriprasad Shivaram Bhat

SAP Cloud Platform Integration- Handling CSV with Header and Footer

Introduction:

Recently came across many questions in our community about handling CSV with Header and footer in SAP Cloud Platform Integration converter step.

Its known to most of the Integration Developers that its not possible to perform the conversion of CSV with headers and Trailer into equivalent XML having header,body and trailer using converter only,so I have tried my best to give some insight on achieving same using Script,Converter,Filter and Content Modifier steps.

Following are the few scenarios I would like to showcase.

Scenario 1:

Convert CSV with Header[ Single Field ] and Trailer to equivalent XML.

Input Data:

HE_XXX_2017052310:20
aaa,123456,abc,fnametest,lnametest2
bbb,123460,xyz,fnametest1,lnametest2 
TR_YYY

Expected Output Data:

<Root>
	<Header>HE_XXX_2017052310:20</Header>
	<Record>
		<Group>aaa</Group>
		<Filenumber>123456</Filenumber>
		<Person>abc</Person>
		<Firstname>fnametest</Firstname>
		<Lastname>lnametest2</Lastname>
	</Record>
	<Record>
		<Group>bbb</Group>
		<Filenumber>123460</Filenumber>
		<Person>xyz</Person>
		<Firstname>fnametest1</Firstname>
		<Lastname>lnametest2</Lastname>
	</Record>
	<Trailer>TR_YYY</Trailer>
</Root>

Whenever we get above requirement first thought would be usage of CSV to XML Converter.Unfortunately it can not be handled using standard converter only.

Integration Process Design:

Below pic more insight on the Solution which can be implemented.

Step 2: Script to filter body without header and trailer.

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

def Message processData(Message message) {
	
	def body= message.getBody(String.class);
	def header_data = body.substring(0, body.indexOf('\n'));
 
	if (header_data != '')
	{
	
	 header_data = header_data.replace('\r','');
	 header_data = header_data.replace('\n','');
	 
 	 message.setProperty("P_FHeader", header_data);
 	 body = body.substring(body.indexOf('\n')+1);
    }


	def footer_data = body.substring(body.lastIndexOf('\n'), body.length());

	if (footer_data != '')
	{
     footer_data = footer_data.replace('\r','');
     footer_data = footer_data.replace('\n','');
   
     message.setProperty("P_FFooter", footer_data);
     body = body.substring(0, body.lastIndexOf('\n'));
	}
	message.setBody(body);
	return message;
}

Step 3: Converter to convert the CSV to XML

Step 4: Content Filter to remove root node created in Converter.

 
Step 5: Content Modifier to rebuild the XML

Scenario 2:

Convert CSV with Header[ Multiple Fields ] and Trailer to equivalent XML.

Input Data:

HE_XXX_2017052310:20,K,L,P
aaa,123456,abc,fnametest,lnametest2
bbb,123460,xyz,fnametest1,lnametest2 
TR_YYY

Expected Output:

<Root>
	<Header>
		<H0>HE_XXX_2017052310:20</H0>
		<H1>K</H1>
		<H2>L</H2>
		<H3>P</H3>
	</Header>
	<Record>
		<Group>aaa</Group>
		<Filenumber>123456</Filenumber>
		<Person>abc</Person>
		<Firstname>fnametest</Firstname>
		<Lastname>lnametest2</Lastname>
	</Record>
	<Record>
		<Group>bbb</Group>
		<Filenumber>123460</Filenumber>
		<Person>xyz</Person>
		<Firstname>fnametest1</Firstname>
		<Lastname>lnametest2 </Lastname>
	</Record>
	<Trailer>TR_YYY</Trailer>
</Root> 

Integration Process Design:

All the steps mentioned in the above scenario remains same except Step 2 [ Script ].

Step 2:

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

def Message processData(Message message) {
	
    def body= message.getBody(String.class);
   
  //Retrieve Header Data
    def header_data = body.substring(0, body.indexOf('\n'));
    if (header_data != '')
    {
    
      header_data = header_data.replace('\r','');
      header_data = header_data.replace('\n','');
      String[] list =header_data.split(",");
      def Header_List= ""
      if (list.length > 0)
      {
         for (int j = 0; j < list.length; j++)
         {
           if(j!= (list.length-1))
             Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"+"\n"
           else
             Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"
         }
       }
   
      message.setProperty("P_FHeader", Header_List);
    //Truncate Header data from body
      body = body.substring(body.indexOf('\n')+1);
     }

    //Retrieve Trailer Data
    def footer_data = body.substring(body.lastIndexOf('\n'), body.length());
    if (footer_data != '')
    {
     footer_data = footer_data.replace('\r','');
     footer_data = footer_data.replace('\n','');
  
     message.setProperty("P_FFooter", footer_data);
    //Truncate Trailer data from body
     body = body.substring(0, body.lastIndexOf('\n'));
    }
    message.setBody(body);
    return message;
}

Conclusion:

Above scenarios can be simplified very much by using Script only,but my intention was to show how other steps can also be used to achieve the required result.Hope it helps beginners to start with File based scenarios with bit of transformation basics.

Thanks & Regards,

Sriprasad Shivaram Bhat

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Very helpful, thank for sharing Shri.

      Author's profile photo Ramu G
      Ramu G

      Hi Shivaram,

      Very useful bog 🙂 I appreciate & thankful for your efforts.How the names got generated for the subnode names under Header [H0,H1,H2,H3]  & Footer[Group,Filenumber,Person,Firstname & Lastname] here.

      Thanks,

      Ramu.

      Author's profile photo Adithya Kambmpati
      Adithya Kambmpati

      Thanks Shiva. Its very helpful blog.

      Author's profile photo Hemachandan A S
      Hemachandan A S

      Very much useful blog for beginners and thanks Sri for sharing.

      Author's profile photo Former Member
      Former Member

      Very nice blog Sri :), thanks for sharing

      Author's profile photo Athar Iqbal
      Athar Iqbal

      Hi Sri, I am trying to convert CSV to XML converter. My issue is that not every row has all the columns filled in and the converter fails with error saying that XSD is expecting more records than the input CSV file. Do we have to have the same number of columns in CSV as defined in XSD?

      Thanks for insight.

      Athar

      Author's profile photo Manjunath GUDISI
      Manjunath GUDISI

      Dear Sriprasad Shivaram Bhat Can I process hundreds of thousands of records in CPI and generate csv file on-the-fly and download csv file to local machine. Can this be somehting possible using CPI? Thanks, Manju

      Author's profile photo Sriprasad S Bhat
      Sriprasad S Bhat

      Hello Manju,

      SAP CPI has the capability to process such huge recrods too.But all it depends is level of transformation and how you are modelling your iflow.

      Regards,

      Sri

      Author's profile photo Manuel Gonzalez
      Manuel Gonzalez

      seems like list.lenght is not longer support

      Original:
            if (list.length > 0)
            {
               for (int j = 0; j < list.length; j++)
               {
                 if(j!= (list.length-1))
                   Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"+"\n"
                 else
                   Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"
               }
             }
      New:
            if (list.size() > 0)
            {
               for (int j = 0; j < list.size(); j++)
               {
                 if(j!= (list.size()-1))
                   Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"+"\n"
                 else
                   Header_List=Header_List+"<H"+j+">"+list[j]+"</H"+j+">"
               }
             }
      Author's profile photo Kushala Dhade
      Kushala Dhade

      Hi Sri,

      Thank you for the excellent Blog,
      The CSV i have is having an extra blank line at the footer hence I'm getting java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: Error.

      How do we remove the blank line and read the line which has the footer data?

      Thank you in advance.

      Regards,

      Kushala