This post describe how to create IS doc From CSV File structure at runtime in webMethods. Generated IS doc confirmed to csv column structure. This method comes very handy to when source can send any format file and can’t confirm structure at runtime. Most of the cases CSV file structure at design time is confirmed and designer can create FlatFile schema\dictionary to parse CSV File using WmFlatFile inbuilt services. however if you want to keep your flow service more adaptive and open to any structure then this method can be very useful.
Code written is in java and use opencsv.
IS doc From CSV File
Code given in this post will help you to create an IS doc from CSV File structure. the only requirement for this code to work is that csv file have at least one record at 0th location and work amazingly if those are the name of columns you want to keep for your field names in IS doc type.
This post have two java service. First one just creates IS Doc from CSV file structure and second one has ability to create IS doc and then parse entire record set as well. you are free to modify java code as it please you.
PS – Please download opencsv jar file from opencsv referral link given above and place in your IS package code\jars folder.
generateISDocType
this java service takes path for csv file and name to be give to generated IS doc and spits out IS doc type in output.
below is screen shot for input\output.
Java Code
import com.opencsv.CSVReader; import com.opencsv.CSVWriter; import java.io.FileReader; import java.io.IOException; import java.io.StringWriter; import java.util.List; import java.util.ArrayList;
Actual java service code
// pipeline IDataCursor pipelineCursor = pipeline.getCursor(); String nameOfGeneratedDoc = IDataUtil.getString( pipelineCursor, "nameOfGeneratedDoc" ); String csvFilePath = IDataUtil.getString( pipelineCursor, "csvFilePath" ); if(nameOfGeneratedDoc == null || nameOfGeneratedDoc.equals("")) nameOfGeneratedDoc = "document"; if(csvFilePath == null || csvFilePath.equals("")) throw new ServiceException("CSV File Path Can't be empty"); try{ CSVReader reader = new CSVReader(new FileReader(csvFilePath)); String[] nextLine = reader.readNext(); // document IData document = IDataFactory.create(); IDataCursor documentCursor = document.getCursor(); int i = 0; while(i < nextLine.length){ IDataUtil.put( documentCursor, nextLine[i], "" ); i++; } documentCursor.destroy(); IDataUtil.put( pipelineCursor, nameOfGeneratedDoc, document ); IDataUtil.remove( pipelineCursor, "csvFilePath"); IDataUtil.remove( pipelineCursor, "nameOfGeneratedDoc"); reader.close(); } catch(Exception e) { throw new ServiceException("Error in reading csv " + e); } pipelineCursor.destroy();
parseCSV
This service accepts path of csv file, other parse related parameters. screen shot below
if skipFirstRecord is set to true, then service assume that first record is name of columns and use them to name fields in IS document. if set to false then file is treated as having only data (no column names).
delimiter is what is used to separate column in file. hence this service supports not only comma separated value but any delimiter.
quoteCharacter by default is double-quoted. you can provide anything here if you have used something else.
use same import statement as for other java service. (these will be automatically present if both java services are created in same folder)
Java Code
// pipeline IDataCursor pipelineCursor = pipeline.getCursor(); boolean skipFirstRecord = IDataUtil.getBoolean( pipelineCursor, "skipFirstRecord" ); String csvFilePath = IDataUtil.getString( pipelineCursor, "csvFilePath" ); String delimiter = IDataUtil.getString( pipelineCursor, "delimiter" ); String quoteCharacter = IDataUtil.getString( pipelineCursor, "quoteCharacter" ); int lineNumber =0; ArrayList parseList = new ArrayList(); String[] columnName = {""}; if(delimiter == null || delimiter.equals("")) delimiter = ","; if(quoteCharacter == null || quoteCharacter.equals("")) quoteCharacter = "\""; try{ //If skipFirstRecord is true then use first record for column names if(skipFirstRecord) { lineNumber = 1; // to use for second reader CSVReader reader1 = new CSVReader(new FileReader(csvFilePath)); columnName = reader1.readNext(); reader1.close(); } CSVReader reader = new CSVReader(new FileReader(csvFilePath), delimiter.charAt(0), quoteCharacter.charAt(0), lineNumber); String[] nextLine; while ((nextLine = reader.readNext()) != null) { IData parseRecord = IDataFactory.create(); IDataCursor parseRecordCursor = parseRecord.getCursor(); int i = 0; while(i < nextLine.length) { if(skipFirstRecord) IDataUtil.put( parseRecordCursor, columnName[i], nextLine[i] ); else IDataUtil.put( parseRecordCursor, "column" + (i+1), nextLine[i] ); i++; } parseRecordCursor.destroy(); parseList.add(parseRecord); } reader.close(); } catch(Exception e) { System.out.println("Error in reading csv " + e); } // document IData document = IDataFactory.create(); IDataCursor documentCursor = document.getCursor(); IDataUtil.put( documentCursor, "record", (IData[]) parseList.toArray(new IData[parseList.size()])); documentCursor.destroy(); IDataUtil.put( pipelineCursor, "document", document ); //remove input IDataUtil.remove( pipelineCursor, "csvFilePath"); IDataUtil.remove( pipelineCursor, "delimiter"); IDataUtil.remove( pipelineCursor, "quoteCharacter"); IDataUtil.remove( pipelineCursor, "skipFirstRecord"); pipelineCursor.destroy(); parseList.clear();
It is pretty simple and straight forward code. Please feel free to modify or improve this code as it suits you.
Please do leave your feedback comments. It help us greatly to improve our post quality.
Questions? Comments? Suggestions? Let us know!! Like / Subscribe / Follow for more updates.