Using Smooks+Mule to transform CSV file to XML one

As I promised before here is an example of how to use Smooks in combination with Mule. In this example I transform a CSV file to a plain XML file. This XML file can then be transformed with an XSLT transformation to the desired XML format.
I start with the Smooks config file ‘smooks-csv-config.xml’:

<?xml version="1.0" encoding="UTF-8"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
                      xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd">
    <csv:reader fields="order_no?trim,cust_no?trim,prod_no?trim,amount?trim"
    separator="|" quote="'" skipLines="0" rootElementName="orders" recordElementName="order" indent="true" />

    <resource-config selector="global-parameters">
        <param name="stream.filter.type">SAX</param>
    </resource-config>
</smooks-resource-list>

The important part is in the ‘csv:reader fields’ attribute. Here I define the fields that can be expected in my input CSV file. As you can see I apply ‘?trim’ to the fields so additional spaces are removed. The important part of the Mule config file is:

<smooks:transformer
        name="csvToXmlSmooksTransformer"
        configFile="/transforms/smooks-csv-config.xml"
        resultType="STRING"
        reportPath="target/smooks-report/report.html"
        />

In the transformer the Smooks config file to be used is defined, so in this case I refer to the one I showed in at the beginning of this post. The next step is to create the test class.:

package net.pascalalma.mule.test;

import java.io.File;
import java.io.InputStream;
import java.util.Locale;
import java.util.TimeZone;

import org.junit.Test;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleMessage;
import org.mule.module.client.MuleClient;
import org.mule.tck.FunctionalTestCase;
import org.mule.util.IOUtils;

public class SmooksCsvTest extends FunctionalTestCase
{
	@Override
	protected String getConfigResources() {
		return "config/smooks-csv-config.xml";
	}

	@Test
	public void testSmooks() throws Exception {
		InputStream in = IOUtils.getResourceAsStream("test-order.csv", this.getClass());

		MuleClient client = new MuleClient();
		MuleMessage reply = client.send("vm://test-csv-to-xml",new DefaultMuleMessage(in));

		assertNotNull(reply);
		assertNotNull(reply.getPayload());

		Object payload = reply.getPayload();
		assertTrue("The message payload is not an instance of String", payload instanceof String);
		assertTrue("The report file wasn't created", getReportFile().exists());
	}

	private File getReportFile() {
		return new File("target/smooks-report/report.html");
	}
	private void deleteReportFile() {
		getReportFile().delete();
	}

	/* (non-Javadoc)
	 * @see org.mule.tck.AbstractMuleTestCase#doSetUp()
	 */
	@Override
	protected void doSetUp() throws Exception {
		super.doSetUp();

		TimeZone.setDefault(TimeZone.getTimeZone("EST"));
		Locale.setDefault(new Locale("en","IE"));
		deleteReportFile();
	}

	/* (non-Javadoc)
	 * @see org.mule.tck.AbstractMuleTestCase#doTearDown()
	 */
	@Override
	protected void doTearDown() throws Exception {
		super.doTearDown();
		deleteReportFile();
	}
}

In the file I read the CSV file and put it on the inbound endpoint. The Smooks transformer is then applied to it and the result is passed to the STDIO outbound. So as a result I expect XML output in my console. The CSV file I used for testing looks like:

1888852| 21625|02745011|31|
1888853| 21625|02745011|71|
1888854| 21625|02745011| 3|

And the result in my console contains:

<orders>
        <order number="1">
                <order_no>1888852</order_no>
                <cust_no>21625</cust_no>
                <prod_no>02745011</prod_no>
                <amount>31</amount>
        </order>
        <order number="2">
                <order_no>1888853</order_no>
                <cust_no>21625</cust_no>
                <prod_no>02745011</prod_no>
                <amount>71</amount>
        </order>
        <order number="3">
                <order_no>1888854</order_no>
                <cust_no>21625</cust_no>
                <prod_no>02745011</prod_no>
                <amount>3</amount>
        </order>
</orders>

Of course this generated XML is very basic but it can be the base for the next (XSLT) transformation step as I said earlier in this post to create a more advanced XML matching your needs.

About Pascal Alma

Pascal is a senior IT consultant and has been working in IT since 1997. He is monitoring the latest development in new technologies (Mobile, Cloud, Big Data) closely and particularly interested in Java open source tool stacks, cloud related technologies like AWS and mobile development like building iOS apps with Swift. Specialties: Java/JEE/Spring Amazon AWS API/REST Big Data Continuous Delivery Swift/iOS
This entry was posted in General, Mule, Smooks and tagged , . Bookmark the permalink.