Converting CSV file to XML using Apache Camel.
Why Apache Camel?
Because Camel Rocks :). Camel has huge transformation libraries which makes code easier and simple to understand and execute. Also Camel is free. It’s an open-source tool with huge user base and nice support.
What’s the Corporate Problem?
Converting CSV to XML is common problem across IT industry where CSV might be the input imported by user and Web-Service might be expecting XML formatted data to run the business logic. Here we will do this conversion in two steps, and both the steps are useful for applicable applications.
Step 1. Converting CSV file to POJO objects (Beans)
Step 2. Converting POJO list to XML using xstream (Open Source easy to use Jar file)
If you are just interested in POJO list, please stop at first step.
Can you run through any example?
Sure thing. Let’s consider we have Employee.csv file having data like below.
employeeId,firstName,lastName,role
23445,Ambarish,Deshpande,Java Lead
23411,Paul,Bulson,Team Member
First we need a bean (DTO) class to map CSV fields. Getters / Setters are optional here.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@CsvRecord(separator = ",", skipFirstLine = true)
public class EmployeeDTO implements Serializable{
@XmlAttribute
@DataField(pos = 1)
private int employeeId;
@XmlAttribute
@DataField(pos = 2)
private String firstName;
@XmlAttribute
@DataField(pos = 3)
private String lastName;
@XmlAttribute
@DataField(pos = 4)
private String role;
}
Annotations?
All @XML* annotations are coming from javax.xml.bind.annotation.* package.
For @CSVRecord and @DataField you have import camel-bindy.jar. I have listed all the dependencies in Appendix section at last.
Now, for actual conversion, camel route must be created.
public class ConvertorRoute implements RoutesBuilder{
@Override
public void addRoutesToCamelContext(CamelContext context) throws Exception {
context.addRoutes(new RouteBuilder() {
public void configure() {
try {
DataFormat bindy = new BindyCsvDataFormat("com.package.dto");
from("file://TEST?fileName=Employee.csv").
unmarshal(bindy).
marshal().
xstream().
to("file://TESTOUT?fileName=employee.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public static void main(String[] args) {
try{
CamelContext context = new DefaultCamelContext();
ConvertorRoute route = new ConvertorRoute();
route.addRoutesToCamelContext(context);
context.start();
Thread.sleep(5000);
context.stop();
}catch(Exception exe){
exe.printStackTrace();
}
}
Steps in Route:
1. Register Bean package (where DTO class resides) with BindyCSVDataFormat.
DataFormat bindy = new BindyCsvDataFormat("com.package.dto");
2. Pick Up the file from TEST folder. (Root//TEST)
3. Unmarshal the csv file with register Bindy. This step creates a List of EmployeeDTO. If intended output is achieved here. Please use this output further.
4. Marshal().xstream() will convert this DTO List to XML and finally
5. Output file will be written on TESTOUT folder as employee.xml file.
Employee.XML file:
<?xml version="1.0" ?>
<list>
<map>
<entry>
<string>com.thd.eai.dto.EmployeeDTO</string>
<com.thd.eai.dto.EmployeeDTO>
<employeeId>23445</employeeId>
<firstName>Ambarish</firstName>
<lastName>Deshpande</lastName>
<role>Lead Java</role>
</com.thd.eai.dto.EmployeeDTO>
</entry>
</map>
<map>
<entry>
<string>com.thd.eai.dto.EmployeeDTO</string>
<com.thd.eai.dto.EmployeeDTO>
<employeeId>23411</employeeId>
<firstName>Paul</firstName>
<lastName>Bulson</lastName>
<role>Team Member</role>
</com.thd.eai.dto.EmployeeDTO>
</entry>
</map>
</list>
Appendix and References:
List of dependencies:
camel-bindy-2.9.0.jar,
camel-core-2.9.0.jar,
camel-csv-2.9.0.jar,
camel-xstream-2.9.0.jar,
slf4j-api-1.6.4.jar,
slf4j-log4j12-1.6.4.jar,
solr-commons-csv-1.3.0.jar,
xstream-1.3.1
Important Links: