Write an XML File using FreeMarker Templates

This example uses TemplateWriter and FreeMarker to generate XML. The TemplateWriter approach uses little overhead and can be used to generate huge XML files (or output streams).

XML Output

The XML resulting from this example will look like the following (line breaks added for clarity).

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<actors>
  <north-america>
    <actor stage-name="John Wayne" real-name="Marion Robert Morrison">
      <gender>male</gender>
      <city>Winterset</city>
      <balance>156.35</balance>
    </actor>
    <actor stage-name="Spiderman" real-name="Peter Parker">
      <gender>male</gender>
      <city>New York</city>
    </actor>
  </north-america>
</actors>

Java Code

The code creates an in-memory reader as the datasource with two records. This can easily be changed to read from a database if needed.

Next we create the TemplateWriter and set the root folder for loading templates along with the header, footer, and detail templates.

package com.northconcepts.datapipeline.examples.cookbook;

import java.io.File;
import java.io.FileWriter;

import com.northconcepts.datapipeline.core.Record;
import com.northconcepts.datapipeline.core.RecordList;
import com.northconcepts.datapipeline.job.Job;
import com.northconcepts.datapipeline.memory.MemoryReader;
import com.northconcepts.datapipeline.template.TemplateWriter;

public class WriteAnXmlFileUsingFreeMarkerTemplates {

    /*
     * Produces the following XML (line breaks added for clarity)
     * 
     *     male Winterset 156.35   male New York   
     * 
     */

    public static void main(String[] args) throws Throwable {

        Record record1 = new Record();
        record1.getField("stageName", true).setValue("John Wayne");
        record1.getField("realName", true).setValue("Marion Robert Morrison");
        record1.getField("gender", true).setValue("male");
        record1.getField("city", true).setValue("Winterset");
        record1.getField("balance", true).setValue(156.35);

        Record record2 = new Record();
        record2.getField("stageName", true).setValue("Spiderman");
        record2.getField("realName", true).setValue("Peter Parker");
        record2.getField("gender", true).setValue("male");
        record2.getField("city", true).setValue("New York");
        record2.getField("balance", true).setValue(-0.96);

        MemoryReader reader = new MemoryReader(new RecordList(record1, record2));

        TemplateWriter writer = new TemplateWriter(new FileWriter("example/data/output/credit-balance-04.xml"));
        writer.setFieldNamesInFirstRow(false);
        writer.getConfiguration().setDirectoryForTemplateLoading(new File("example/data/input"));
        writer.setHeaderTemplate("WriteAnXmlFileUsingFreeMarkerTemplates-header.xml");
        writer.setFooterTemplate("WriteAnXmlFileUsingFreeMarkerTemplates-footer.xml");
        writer.setDetailTemplate("WriteAnXmlFileUsingFreeMarkerTemplates-detail.xml");

        Job.run(reader, writer);
    }

}

FreeMarker Templates

Three FreeMarker templates will be used together to generate XML: header, detail, and footer.

Header

The header template (WriteAnXmlFileUsingFreeMarkerTemplates-header.xml) contains the XML declaration and opening tags.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<actors>
	<north-america>

Detail

The detail template (WriteAnXmlFileUsingFreeMarkerTemplates-detail.xml) contains the FreeMarker code to convert each record to XML. Each field's value is automatically added to the template's model and can be used by referencing its name. The template also includes a record variable of type com.northconcepts.datapipeline.core.Record that can also be referenced if needed.

		<actor stage-name="${stageName}" real-name="${realName}">
			<gender>${gender}</gender>
			<city>${city}</city>
			<#if (balance >= 0)>
				<balance>${balance}</balance>
			</#if>
		</actor>

Footer

The footer template (WriteAnXmlFileUsingFreeMarkerTemplates-footer.xml) contains the closing XML tags.

	</north-america>
</actors>
Mobile Analytics