开发者

XML to Java mapping tool - with mapping descriptor

I am trying to find a library that allows me to place the content of an XML into a JavaBean (something like Digester, Jaxb, JIXB etc) but I ne开发者_StackOverflow中文版ed it to be runtime (not at compile time, or by byte code generation) and use a mapping file of some sort.

The idea will be something like Hibernate's HBM mapping files, a way to specify which XML element goes into which Java property. I am currently using Digester but I want something simpler for its rules file.

This should also work on a 1.4 JDK so annotations won't really do (but I will consider such responses just for completeness's sake).

To resume, I need a runtime tool that does XML to Java based on a XML descriptor of some sort, something like this (taken from JIXB) but at runtime (i.e. pass it the XML, the Java class to output object and the mapping descriptor):

XML to Java mapping tool - with mapping descriptor

Do you know of such a library?

Thank you!


Try XSLT.

You can take you input XML file and transform it in another XML file that will be the input for Jaxb/XmlBeans/... to populate your bean.

The XSL file will be the "runtime" configuration that will describe the mapping.

Input XML ---(XSLT)---> Bean XML ---(Jaxb)---> Java bean


Try Castor. It is able to generate java code from DTD (and probably from XSD too). So, you can generate the code at runtime and then compile it.

BTW check JAXB again. I believe that it can do the same.


Hibernate actually has some support for XML mapping. See the doc for more infos. I did a PoC some time ago, and found it a bit lacking on the documentation. I didnt find how to use namespaces properly.

We finally used Rome as we only needed to parse / generate Atom feeds with custom namespaces. But I dont think Rome will solve your problem. The mappings are done in Java code, and it is restricted in parsing / generating RSS / Atom ...

Good luck ! And if you end up using Hibernate, I'd love to know how it is working for you !


Apache Commons Digester should probably be a interesting tool to consider. It does what you need, i.e. take a XML and transform it into a Java bean.


EclipseLink JAXB (MOXy) (I'm the tech lead) has an XML mapping file. For your example the mapping file would be:

binding.xml

<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="blog.bindingfile">
    <java-types>
        <java-type name="Customer">
            <xml-root-element/>
            <xml-type prop-order="person street city state zip phone"/>
        </java-type>
        <java-type name="Person">
            <xml-type prop-order="customerNumber firstName lastName"/>
            <java-attributes>
                <xml-element java-attribute="customerNumber" name="cust-num"/>
                <xml-element java-attribute="firstName" name="first-name"/>
                <xml-element java-attribute="lastName" name="last-name"/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

Domain Model

This would map the following classes:

package blog.bindingfile;

public class Customer {

    public Person person;
    public String street;
    public String city;
    public String state;
    public Integer zip;
    public String phone;

}

package blog.bindingfile;

public class Person {

    public int customerNumber;
    public String firstName;
    public String lastName;

}

XML

To/from the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<customer>
    <person>
        <cust-num>123456789</cust-num>
        <first-name>John</first-name>
        <last-name>Smith</last-name>
    </person>
    <street>12345 Happy Lane</street>
    <city>Plunk</city>
    <state>WA</state>
    <zip>98059</zip>
    <phone>888.555.1234</phone>
</customer>

Demo Code

As demonstrated by:

package blog.bindingfile;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

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, new File("binding.xml"));
        JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", Customer.class.getClassLoader() , properties);

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

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

}

jaxb.properties

To use MOXy as your JAXB implementation you need to include a jaxb.properties file with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Note

This example uses the simplified bootstrapping available in the upcoming EclipseLink 2.2 release. For an example using EclipseLink 2.1 see:

  • http://wiki.eclipse.org/EclipseLink/Examples/MOXy/EclipseLink-OXM.XML
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜