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:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
  3.                       xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd">
  4.     <csv:reader fields="order_no?trim,cust_no?trim,prod_no?trim,amount?trim"
  5.     separator="|" quote="'" skipLines="0" rootElementName="orders" recordElementName="order" indent="true" />
  6.  
  7.     <resource-config selector="global-parameters">
  8.         <param name="stream.filter.type">SAX</param>
  9.     </resource-config>
  10. </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.
My Mule config file 'smooks-csv-config' that is used for this test can be found here. The important part looks like:

XML:
  1. <smooks:transformer
  2.         name="csvToXmlSmooksTransformer"
  3.         configFile="/transforms/smooks-csv-config.xml"
  4.         resultType="STRING"
  5.         reportPath="target/smooks-report/report.html"
  6.         />

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.:

JAVA:
  1. package nl.redstream.mule.test;
  2.  
  3. import java.io.File;
  4. import java.io.InputStream;
  5. import java.util.Locale;
  6. import java.util.TimeZone;
  7.  
  8. import org.junit.Test;
  9. import org.mule.DefaultMuleMessage;
  10. import org.mule.api.MuleMessage;
  11. import org.mule.module.client.MuleClient;
  12. import org.mule.tck.FunctionalTestCase;
  13. import org.mule.util.IOUtils;
  14.  
  15. public class SmooksCsvTest extends FunctionalTestCase
  16. {
  17.     @Override
  18.     protected String getConfigResources() {
  19.         return "config/smooks-csv-config.xml";
  20.     }
  21.  
  22.     @Test
  23.     public void testSmooks() throws Exception {
  24.         InputStream in = IOUtils.getResourceAsStream("test-order.csv", this.getClass());
  25.  
  26.         MuleClient client = new MuleClient();
  27.         MuleMessage reply = client.send("vm://test-csv-to-xml",new DefaultMuleMessage(in));
  28.  
  29.         assertNotNull(reply);
  30.         assertNotNull(reply.getPayload());
  31.  
  32.         Object payload = reply.getPayload();
  33.         assertTrue("The message payload is not an instance of String", payload instanceof String);
  34.         assertTrue("The report file wasn't created", getReportFile().exists());
  35.     }
  36.  
  37.     private File getReportFile() {
  38.         return new File("target/smooks-report/report.html");
  39.     }
  40.     private void deleteReportFile() {
  41.         getReportFile().delete();
  42.     }
  43.  
  44.     /* (non-Javadoc)
  45.      * @see org.mule.tck.AbstractMuleTestCase#doSetUp()
  46.      */
  47.     @Override
  48.     protected void doSetUp() throws Exception {
  49.         super.doSetUp();
  50.  
  51.         TimeZone.setDefault(TimeZone.getTimeZone("EST"));
  52.         Locale.setDefault(new Locale("en","IE"));
  53.         deleteReportFile();
  54.     }
  55.  
  56.     /* (non-Javadoc)
  57.      * @see org.mule.tck.AbstractMuleTestCase#doTearDown()
  58.      */
  59.     @Override
  60.     protected void doTearDown() throws Exception {
  61.         super.doTearDown();
  62.         deleteReportFile();
  63.     }
  64. }

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:

XML:
  1. <orders>
  2.         <order number="1">
  3.                 <order_no>1888852</order_no>
  4.                 <cust_no>21625</cust_no>
  5.                 <prod_no>02745011</prod_no>
  6.                 <amount>31</amount>
  7.         </order>
  8.         <order number="2">
  9.                 <order_no>1888853</order_no>
  10.                 <cust_no>21625</cust_no>
  11.                 <prod_no>02745011</prod_no>
  12.                 <amount>71</amount>
  13.         </order>
  14.         <order number="3">
  15.                 <order_no>1888854</order_no>
  16.                 <cust_no>21625</cust_no>
  17.                 <prod_no>02745011</prod_no>
  18.                 <amount>3</amount>
  19.         </order>
  20. </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.