I'm in a situation where I need to create and parse a set of xml's that are quite similar in structure but unfortunately have been defined in several different namespaces. I'm generally able to parse and create all the XML's using JAXB, but seems to have some problems getting JAXB to handle the namespace definitions. The following simple example should illustrate the problem.
If I define an annotated class with a namespace like this:
Bus.java:
@XmlRootElement(name = "Bus", namespace = "http://www.example.org/bus")
@XmlAccessorType(XmlAccessType.FIELD)
public class Bus {
@XmlElement(name = "Driver")
Driver driver;
}
And define another class used by this class without specifying a namespace
Driver.java:
@XmlAccessorType(XmlAccessType.FIELD)
public class Driver {
@XmlElement(name = "DriverName")
String driverName;
}
And at the same time I have the following package level definition that allows me to use the Driver class in the namespace of Bus without explicitly defining it's namespace in the class:
package-info.java
@XmlSchema(namespace = "http://www.example.org/bus",
xmlns = { @XmlNs(prefix = "", namespaceURI = "http://www.example.org/bus") }
, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
And I have an xml like this:
String xml = "<Bus xmlns=\"http://www.example.org/bus\">" +
" <Driver>" +
" <DriverName>Bob</DriverName>" +
" </Driver>" +
"</Bus>";
Then I can simply parse / recreate the xml using something like this:
JAXBContext context = JAXBContext.newInstance(Bus.class);
// parse xml
Unmarshaller um = context.createUnmarshaller();
Object xmlObj = um.unmarshal(new StringReader(xml));
// recreate xml
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter sw = new StringWriter();
marshaller.marshal(xmlObj, sw);
String recreatedXml = sw.toString();
System.out.println("recreatedXml);
That gives:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Bus xmlns="http://www.example.org/bus">
<Driver>
<DriverName>Bob</DriverName>
</Driver>
</Bus>
But how do I go about reusing the Driver class in another namespace e.g. like this ?
Car.java
@XmlRootElement(name = "Car", namespace = "http://www.example.org/car")
@XmlAccessorType(XmlAccessType.FIELD)
public class Car {
@XmlElement(name = "Driver")
Driver driver;
}
package-info.java only allows for one XmlSchema, and without it, each field seems to need an explicit namespace.