Parsing/Deserialize XML to JavaObjects

18,749

Solution 1

use

xjc your_xsd_name -p packagename 

to generate Pojos, xjc is xml java compiler that comes with jdk.

once your classes are generated use jaxb as follows

JAXB Marshalling

    HDB hdb = new HDB(); 
    JAXBContext jaxbContext = JAXBContext.newInstance(HDB.class);
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.marshal(hdb, file);
    jaxbMarshaller.marshal(hdb, System.out);

JAXB Unmarshalling

    File file = new File("your xml file");
    JAXBContext jaxbContext = JAXBContext.newInstance(hdb.class);

    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    HDB hdb = (HDB) jaxbUnmarshaller.unmarshal(file);
    System.out.println(hdb);

Visit following link for more info JAXB marshalling and unmarshalling

Solution 2

JAXB - Java to XML binding, is the way to go for effective and efficient XML to POJO and vice versa as pointed by above example.

Plus required tools are bundled with JDK only requirement is error free XSD/set of XSDs required for creating object bindings.

XJC

xjc : with either command line args as -p for package name -d for out dir etc. details can be found on xjc man page/refer Online page.

But if implementation involves multiple xsds, then prefer using xjb (binding file)

<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              version="2.1" jxb:extensionBindingPrefixes="xjc">
    <jxb:globalBindings>
        <xjc:simple/>
    </jxb:globalBindings>
    <jxb:bindings schemaLocation="schema/xml/xmldsig-core-schema.xsd">
        <jxb:schemaBindings>
            <jxb:package name="org.w3.xmldsig"/>
        </jxb:schemaBindings>
    </jxb:bindings>
    <jxb:bindings schemaLocation="schema/xml/xenc-schema.xsd">
        <jxb:schemaBindings>
            <jxb:package name="org.w3.xenc"/>
        </jxb:schemaBindings>
    </jxb:bindings>
</jxb:bindings>

Comprehensive guide from oracle on XJBs Guide

Once you have your bindings generated, all you need is create JAXBContext with either class or list of packages separated by :

final JAXBContext context = JAXBContext.newInstance(Generated.class);
final JAXBContext contextOnPackage = JAXBContext.newInstance("com.alpha.generated:com.beta.generated");

optionally you can provide a Classloader as well final JAXBContext contextCustomClassLoader = JAXBContext.newInstnace("..:..", X.class.getClassLoader()); // this is for more advanced use.

UnMarshalling

// source can be a file/InputStream/InputSource etc.  
Test obj = (Test)context.createUnMarshaller().unmarshal(source);

Marshalling

Test test = gen.xml.package.ObjectFactory.createTest();  
// Bunch of setters   
// gen.xml.package is generated package XJC will create ObjectFactory as well  
// sink can be File/OutputStream/Writer etc.  
context.createMarshaller().marshal(test, sink);

For more details refer to Javadocs and JAXB Specifications.

Share:
18,749
Smoki
Author by

Smoki

Updated on August 19, 2022

Comments

  • Smoki
    Smoki over 1 year

    i started a small new project and i want to deserialize objects from XML.

    i created a xsd:

    http://pastebin.com/n1pwjRGX

    and an example XML File :

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <hdb>
        <country code="DE">
            <variableHoliday daysAfterEaster="49" name="PENTECOAST" />
            <fixedHoliday month="JANUARY" day="1" name="NEWYEAR" />
            <region code="sa">
                <fixedHoliday month="APRIL" day="1" name="FUNNYDAY" />
                <variableHoliday daysAfterEaster="0" name="EASTERSUNDAY" />
            </region>
            <region code="ba">
                <variableHoliday daysAfterEaster="12" name="CORPUSCHRISTI" />
            </region>
        </country>
        <country code="US">
            <fixedHoliday month="JULY" day="4" name="INDEPENDENCEDAY" />
        </country>
        <country code="AL">
            <fixedHoliday month="JULY" day="4" name="INDEPENDENCEDAY" />
        </country>
    </hdb>
    

    Which should use the xsd and so on.

    So how can i achive the deserialization of these XML to a nice Java-Object Structure?

    Mabe like :

    class HDB {
        private HashMap<CountryCode,Country> map;
    }
    
    class Country {
        private List<Holiday> list; // or two Lists with <variableHoliday> and <fixedHoliday>
        private List<Region> regions;
    }
    
    class Region{
        private List<Holiday> list; // or two Lists with <variableHoliday> and <fixedHoliday>
    }
    
    class variableHoliday {
        private String name;
        private int daysAfterEaster;
    }
    class fixedHoliday {
        private String name;
        private int day;
        private MonthName month; // while MonthName is an enum defined like the enum from XSD
    }
    

    Any ideas how to achive that easy?

    I thought of jaxb an tried some stuff, but it seems to me (im a beginner with jaxb) that its hard to achive this XML structure because of maps cant be written like v.

  • Smoki
    Smoki almost 10 years
    wow great man, i didn't know that tool. thats some real great stuff o.O , thanks!!
  • andrej
    andrej about 7 years
    one need to add the JAXB XmlRootElement, XmlAttribute and XmlElement annotations to POJO class setters to let JAXB mapping engine do it's stuff.