Serialize DataMapping containing special characters to XML

This example shows you how to serialize DataMapping and other DP Foundations objects to XML containing special characters with JDK 19 and onwards.

The XML generated by serialization does not contain the XML declaration or encoding heading. It uses the default configuration of xml version 1.0 and UTF-8 encoding.

From JDK 19 onwards, XML 1.0 serialization does not support some special ASCII characters. For example, character 1 (start of heading), 2 (start of text), 3 (end of text), etc. However, these characters are supported by XML version 1.1. This example shows how to set XML version 1.1 during XML serialization.

Consider the following DataMapping:


Java Code Listing

package com.northconcepts.datapipeline.foundations.examples.datamapping;

import com.northconcepts.datapipeline.foundations.datamapping.DataMapping;

public class SerializeDataMappingContainingSpecialCharactersToXML {

	public static void main(String[] args) {
		DataMapping mapping = new DataMapping()
				// Description contains special character SOH (start of heading)
				.setDescription("DataMapping for user table having start of heading character" + ((char) 01))
				.addFieldMapping("first_name", "source.fname")
				.addFieldMapping("last_name", "toUpperCase(source.lname)")
				.addFieldMapping("name", "source.fname + ' ' + target.last_name")
				.addFieldMapping("name_length", "length(target.name)");

		/*
		 * Default XML version 1.0 is used in XML Serialization.
		 * JDK 19 (and onwards) will throw an exception because of special character.
		 */
		try {
			System.out.println(mapping.toXml());
		} catch (Throwable e) {
			e.printStackTrace();
		}

		System.out.println("===============================================================================");

		/*
		 * From JDK 19 onwards, to serialize such special characters, XML version 1.1 is required.
		 * To Enable XML version 1.1 declaration, consider this snippet.
		 */
		System.out.println(mapping.toXml(true));
	}

}


Code Walkthrough

  1. Create the DataMapping object with the necessary details. Please note that the description has special character (ASCII 1) at the end.
  2. JDK 19 an onwards will throw an exception for such special characters during XML serialization. See output for the example.
  3. To serialize such special character, you can declare XML version 1.1 by setting the boolean argument to true

Output

com.northconcepts.datapipeline.core.DataException:  org.xml.sax.SAXException: An invalid XML character (Unicode: 0x1) was found in the node's character data content.
-------------------------------
	at com.northconcepts.datapipeline.core.DataException.wrap(DataException.java:68)
	at com.northconcepts.datapipeline.core.XmlSerializable.writeXml(XmlSerializable.java:141)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:75)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:67)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:52)
	at com.northconcepts.datapipeline.foundations.examples.datamapping.SerializeDataMappingContainingSpecialCharactersToXML.main(SerializeDataMappingContainingSpecialCharactersToXML.java:27)
javax.xml.transform.TransformerException: org.xml.sax.SAXException: An invalid XML character (Unicode: 0x1) was found in the node's character data content.
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:792)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:395)
	at com.northconcepts.datapipeline.core.XmlSerializable.writeXml(XmlSerializable.java:120)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:75)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:67)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:52)
	at com.northconcepts.datapipeline.foundations.examples.datamapping.SerializeDataMappingContainingSpecialCharactersToXML.main(SerializeDataMappingContainingSpecialCharactersToXML.java:27)
Caused by: org.xml.sax.SAXException: An invalid XML character (Unicode: 0x1) was found in the node's character data content.
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.accumDefaultEscape(ToStream.java:1749)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.writeAttrString(ToStream.java:2062)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.processAttributes(ToStream.java:2016)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.closeStartTag(ToStream.java:2536)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.startElement(ToStream.java:1873)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToUnknownStream.startElement(ToUnknownStream.java:480)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToUnknownStream.startElement(ToUnknownStream.java:413)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:151)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:229)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:134)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:96)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:718)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:780)
	... 6 more
---------
org.xml.sax.SAXException: An invalid XML character (Unicode: 0x1) was found in the node's character data content.
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.accumDefaultEscape(ToStream.java:1749)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.writeAttrString(ToStream.java:2062)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.processAttributes(ToStream.java:2016)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.closeStartTag(ToStream.java:2536)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToStream.startElement(ToStream.java:1873)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToUnknownStream.startElement(ToUnknownStream.java:480)
	at java.xml/com.sun.org.apache.xml.internal.serializer.ToUnknownStream.startElement(ToUnknownStream.java:413)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:151)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:229)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:134)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.DOM2TO.parse(DOM2TO.java:96)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:718)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:780)
	at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:395)
	at com.northconcepts.datapipeline.core.XmlSerializable.writeXml(XmlSerializable.java:120)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:75)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:67)
	at com.northconcepts.datapipeline.core.XmlSerializable.toXml(XmlSerializable.java:52)
	at com.northconcepts.datapipeline.foundations.examples.datamapping.SerializeDataMappingContainingSpecialCharactersToXML.main(SerializeDataMappingContainingSpecialCharactersToXML.java:27)
===============================================================================
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<data-mapping description="DataMapping for user table having start of heading character&#1;">
  <field-mappings>
    <field-mapping fieldName="first_name" sourceExpression="source.fname"/>
    <field-mapping fieldName="last_name" sourceExpression="toUpperCase(source.lname)"/>
    <field-mapping fieldName="name" sourceExpression="source.fname + ' ' + target.last_name"/>
    <field-mapping fieldName="name_length" sourceExpression="length(target.name)"/>
  </field-mappings>
</data-mapping>
Mobile Analytics