Reputation: 561
i started a small new project and i want to deserialize objects from XML.
i created a xsd:
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.
Upvotes: 5
Views: 23130
Reputation: 137
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 : 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.
// source can be a file/InputStream/InputSource etc.
Test obj = (Test)context.createUnMarshaller().unmarshal(source);
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.
Upvotes: 2
Reputation: 3320
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
Upvotes: 7