1

I want to convert XML to Java objects. But I do not wish to hard code the mapping between XML tags and Java classes in the code, like for example using JAXB annotations or XStream.alias() method.

How do I achieve this?

Thanks!

Pranav Pal
  • 275
  • 6
  • 18

2 Answers2

2

Then you should choose an XML parser and design your own unmarshaller. On the other hand JAXB can unmarshall xml into a Java bean without annotations, see this code, it works

public class Test {
    private String e1;

    public String getE1() {
        return e1;
    }

    public void setE1(String e1) {
        this.e1 = e1;
    }

    public static void main(String[] args) throws Exception {
        String xml = "<Test><e1>test</e1></Test>";
        Test t = JAXB.unmarshal(new StringReader(xml), Test.class);
        System.out.println(t.getE1());
    }
}
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • important thing to note in this answer that why JAXB is able to unmarshall the xml into Test.java is because the classname and XML root element tag are same, this is almost like hard coding the mappings through annotations. – Sikorski Dec 05 '12 at 05:46
  • 1
    right, just wanted to show that it is possible to use JAXB without annotations – Evgeniy Dorofeev Dec 05 '12 at 05:55
1

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

In the EclipseLink MOXy implementation of JAXB we offer an external mapping document that can be used as an alternative to the standard annotations.

oxm.xml

Below is a sample mapping document.

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="blog.bindingfile">
    <xml-schema
        namespace="http://www.example.com/customer"
        element-form-default="QUALIFIED"/>
    <java-types>
        <java-type name="Customer">
            <xml-root-element/>
            <xml-type prop-order="firstName lastName address phoneNumbers"/>
            <java-attributes>
                <xml-element java-attribute="firstName" name="first-name"/>
                <xml-element java-attribute="lastName" name="last-name"/>
                <xml-element java-attribute="phoneNumbers" name="phone-number"/>
            </java-attributes>
        </java-type>
        <java-type name="PhoneNumber">
            <java-attributes>
                <xml-attribute java-attribute="type"/>
                <xml-value java-attribute="number"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Demo

Below is an example of how to specify the external mapping document when bootstrapping a JAXBContext.

package blog.bindingfile;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>(1);
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "blog/bindingfile/binding.xml");
        JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", Customer.class.getClassLoader() , properties);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Customer customer = (Customer) unmarshaller.unmarshal(new File("src/blog/bindingfile/input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }

}

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400