<?xml version="1.0" encoding="ISO-8859-1"?>
<document url="http://castor.org/howto/how-to-unmarshal-raw-xml.xml">
  <properties>
    <title>How to Unmarshal raw XML segments into arbitrary types</title>
    <abstract/>
    <status>Final</status>
  </properties>
  <body>
    <title>How to Unmarshal raw XML segments into arbitrary types</title>
    <header/>

    <section title="Intended Audience">

        <p>Anyone who wants to map raw XML segments into data types.</p>
        
    </section>
    
    <section title="Prerequisites">

        <p>None.</p>

    </section>

    <section title="Basic concept">
        
        <p>Lets say you have an XML structure:</p>
           
        <code-panel><![CDATA[
<root>
	<xmlnode attribute="misc xml data">
		<data>Data 1</data>
		<data>Data 2</data>
	</xmlnode>
	<string>Regular String Data</string>
	<xmlnode2>
		<misc>Misc xml to be dealt with later</misc>
	</xmlnode2>
</root>]]></code-panel>
           
        <p>And you want to save off portions of this XML in your objects, instead of
           having Castor map them immediately.</p>
           
        <code-panel>
package bizobj;

public class Root {
	private Object anyType;
	private String stringData;
	private String stringXML;
	
	public Object getAnyType() {
		return anyType;
	}
	public void setAnyType(Object anyType) {
		this.anyType = anyType;
	}
	public String getStringData() {
		return stringData;
	}
	public void setStringData(String stringData) {
		this.stringData = stringData;
	}
	public String getStringXML() {
		return stringXML;
	}
	public void setStringXML(String stringXML) {
		this.stringXML = stringXML;
	}
}</code-panel>

        <p>There are two approaches that can be used for this. The first, approach
           would be to use the AnyNode type. The benefits of this approach is that
           you do not have to do anything special to get the data in the mapping
           file, and can both unmarshal and marshal the xml data. The drawback is
           that you have to call toString() on the object to get the XML.</p>
           
        <p>The second approach is to use a custom FieldHandler implementation to
           convert the values. The benefit of this approach is that you are able to
           convert into any type you want. The drawback is that there is currently
           no way to marshal the xml data back into XML. It ends up as XML encoded
           data inside the marshalled XML.</p>
           
    </section>

    <section title="Mapping file">

        <p>Here is an example mapping file that includes both examples.</p>

        <code-panel><![CDATA[
<?xml version="1.0"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
                         "http://castor.org/mapping.dtd">
<mapping>
	<class name="bizobj.Root">
		<field name="anyType" type="java.lang.Object">
			<bind-xml name="xmlnode" node="element" />
		</field>

		<field name="stringData" type="string">
			<bind-xml name="string" node="element" />
		</field>

		<field name="stringXML" type="java.lang.Object" handler="MyHandler">
			<bind-xml name="xmlnode2" node="element" />
		</field>
	</class>
</mapping>]]></code-panel>
    
        <p>The anyType field is set to java.lang.Object. Behind the scenes it is
           actually an AnyType object.</p>

        <p>Also, notice that the stringXML field is of type java.lang.Object. This
           is because Castor looks at that first to determine what type of parsing
           needs to be done, then passes it on to the Field Handler, which converts
           it into whatever is desired.</p>

        <p>Here is an example Field Handler that converts the input into a string.</p>

        <code-panel>
import org.exolab.castor.mapping.GeneralizedFieldHandler;

public class MyHandler extends GeneralizedFieldHandler {
	public Object convertUponGet(Object value) {
		return (value == null) ? null : value.toString();
	}	

	public Object convertUponSet(Object value) {
		return (value == null) ? null : value.toString();
	}

	public Class getFieldType() {	return String.class; }
}</code-panel>

    </section>

    <section title="References">

        <ul>
            <li><a href="xml-mapping.html">XML mapping</a></li>
            <li><a href="xml-fieldhandlers.html">Custom Handlers</a></li>
        </ul>
        
    </section>


  </body>
</document>
