You can use the @XmlPath extension in EclipseLink JAXB (MOXy) to fulfill this use case (I am the leader of MOXy tech):
Root
JAXB requires one object to be unmarshal, we will introduce a class to fulfill this role. This class will have fields corresponding to two objects that you want to decouple with annotation using your own XPath: @XmlPath (".")
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement(name="type") @XmlAccessorType(XmlAccessType.FIELD) public class Root { @XmlPath(".") private Item item; @XmlPath(".") private ItemDimensions itemDimensions; }
ItemDimensions
You usually comment on this class. In your example, you are commenting on properties, but only providing getters. This will make JAXB think these are write-only records.
import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class ItemDimensions { private Integer height; private Integer width; private Integer depth; }
Item
import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Item { private Integer id; private Double cost; }
Demo
import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Unmarshaller u = jc.createUnmarshaller(); Object o = u.unmarshal(new File("input.xml")); Marshaller m = jc.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.marshal(o, System.out); } }
jaxb.properties
To use MOXy as your JAXB implementation, you must provide a file named jaxb.properties in your domain objects with the following entry:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
source share