Data Transformation: CSV to XML With Apache Camel
Learn how to convert a CSV message into XML using Camel Apache Processor, or from any format into another, with code examples.
Join the DZone community and get the full member experience.
Join For Free1.0 Overview
Data Transformation means transforming data from one form to another. For example, XML to CSV, XML to JSON, etc. Data Transformation in Apache Camel can be achieved by using Processor in routing logic, using bean, or by using Transform() in DSL.
In this article, we will see how to transform CSV to XML using Processor in routing logic.
2.0 Camel Processor
Camel Processor is one of the key building blocks, and it gives access to the full message transferred, including body, headers, and properties associated with the message. By creating a processor, you can modify any elements or properties of the message body; for example, you can add custom properties to the header, transforming the message from CSV to XML, etc.
Camel Processor is interface defined in org.apache.camel.processor, having a single method.
public void process(Exchange exchange) throws Exception
3.0 Input and Output Message
In this article, you will see how to convert CSV into XML using Processor. Below are the input and output message.
3.1 Input Message (CSV)
1,Robert,3000
2,James,3000
3,Steve,5000
4,Brian,7000
5,Christian,6000
3.2 Output Message (XML)
<Employees>
<Employee>
<EmployeeID>1</EmployeeID>
<Name>Robert</Name>
<Salary>3000</Salary>
</Employee>
<Employee>
<EmployeeID>2</EmployeeID>
<Name>James</Name>
<Salary>3000</Salary>
</Employee>
<Employee>
<EmployeeID>3</EmployeeID>
<Name>Steve</Name>
<Salary>5000</Salary>
</Employee>
<Employee>
<EmployeeID>4</EmployeeID>
<Name>Brian</Name>
<Salary>7000</Salary>
</Employee>
<Employee>
<EmployeeID>5</EmployeeID>
<Name>Christian</Name>
<Salary>6000</Salary>
</Employee>
</Employees>
4.0 Code
In this class, you will see the Camel route has been defined, with the process route calling the MyTransform class, which is actually transforming CSV into an XML message.
package com.CSVToXML.demo;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.builder.RouteBuilder;
public class CSVToXMLTransformation {
public static void main(String[] args) throws Exception {
CamelContext _ctx=new DefaultCamelContext();
_ctx.addRoutes(new RouteBuilder(){
public void configure() throws Exception
{
from("file:D:\\ApacheCamel\\Demo1\\IN")
.process(new MyTransform())
.to("file:D:\\ApacheCamel\\Demo1\\OUT?fileName=emp.xml");
}
});
_ctx.start();
Thread.sleep(4000);
_ctx.stop();
}
}
In the process method, you will get input data as an exchange object. Here, we are reading the exchange object as a string and converting CSV into XML. Finally, the transformed message is set as the exchange.
package com.CSVToXML.demo;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
public class MyTransform implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
String myString = exchange.getIn().getBody(String.class);
String[] lineSeparator = myString.split(System.getProperty("line.separator"));
StringBuffer sb = new StringBuffer();
sb.append("<Employees>");
for (String lineData : lineSeparator)
{
String [] commaSeparator=lineData.split(",");
sb.append("<Employee>");
sb.append("<EmployeeID>"+commaSeparator[0].toString()+"</EmployeeID>");
sb.append("<Name>"+commaSeparator[1].toString()+"</Name>");
sb.append("<Salary>"+commaSeparator[2].toString()+"</Salary>");
sb.append("</Employee>");
}
sb.append("</Employees>");
System.out.println("MyProcessor complete");
exchange.getIn().setBody(sb.toString());
}
}
5.0 Spring DSL
If you prefer to use Spring DSL, then the same result can be achieved by using the below XML.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/bean">
<bean id="myTransform" class="com.CSVToXML.demo.MyTransform" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:D:\\ApacheCamel\\Demo1\\IN" />
<process ref="myTransform" />
<to uri="file:D:\\ApacheCamel\\Demo1\\OUT?fileName=emp.xml" />
</route>
</camelContext>
</beans>
6.0 CSV To XML Using Marshalling and Unmarshalling
6.1 Define Employee Bean Class
package com.learncamel.processor;
public class Employee {
private String EmployeeID;
private String Name;
private String Salary;
public String getEmployeeID() {
return EmployeeID;
}
public void setEmployeeID(String employeeID) {
EmployeeID = employeeID;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getSalary() {
return Salary;
}
public void setSalary(String salary) {
Salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"EmployeeID='" + EmployeeID + '\'' +
", Name='" + Name + '\'' +
", Salary='" + Salary + '\'' +
'}';
}
}
6.2 Define Processor
package com.learncamel.processor;
import com.learncamel.domain.Employee;
import org.apache.camel.Exchange;
import java.util.StringTokenizer;
import org.apache.camel.Exchange;
public class CustomProcessorXStream implements org.apache.camel.Processor {
public void process(Exchange exchange) throws Exception {
String newBody = exchange.getIn().getBody(String.class);
StringTokenizer tokenizer = new StringTokenizer(newBody, ",");
Employee employee = new Employee();
while (tokenizer.hasMoreElements()){
employee.setEmployeeID((String) tokenizer.nextElement());
employee.setName((String) tokenizer.nextElement());
employee.setSalary((String) tokenizer.nextElement());
}
exchange.getIn().setBody(employee);
}
}
6.3 Define Camel Route
package com.learncamel.route.xstream;
import com.learncamel.processor.CustomProcessorXStream;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.dataformat.xstream.XStreamDataFormat;
import com.learncamel.domain.Employee;
import java.util.HashMap;
import java.util.Map;
public class MarshalUsingXStream extends RouteBuilder{
public void configure() throws Exception {
from("direct:csvinput")
.process(new CustomProcessorXStream())
//.marshal().xstream()
.marshal(populateStreamDef())
.to("log:?level=INFO&showBody=true")
.to("mock:output");
}
private XStreamDataFormat populateStreamDef() {
XStreamDataFormat xstreamDefinition = new XStreamDataFormat();
Map<String, String> aliases = new HashMap<String, String>();
aliases.put("Employee", Employee.class.getName());
xstreamDefinition.setAliases(aliases);
return xstreamDefinition;
}
}
7.0 Conclusion
It is very easy to transform one message format into another using Apache Camel. There are different ways provided by Camel to transform the message. In this article, we have made use of Processor in routing logic, and in the next articles, you will see how to transform a message using bean and the Transform ()
method.
Now you know how to transform CSV into XML using Apache Camel.
Opinions expressed by DZone contributors are their own.
Comments