Suppose you have one xml document like this
<product>
<name>MicroWave</name>
<extra>
<!-- undefined xml content from other source -->
</extra>
</product>
The xml document will be generated by JAXB marshaller(A).
Suppose the XML content enclosed by extra tag is from another JAXB marshaller(B), how can we insert the result from B to the location under Extra.
First, define the extra has the type xsd:anyType. You can do this in schema, annotation. For eclipselink xom, your property will be xml-anyelement instead of the regular xml-element.
Second, define a XmlAdapter which will use the unmarshaller B to convert java object into a org.w3c.dom.Element. The Element will be marshalled in place.
public class ObjectAdapter extends XmlAdapter<Element, Object>
{
@Override
public Element marshal(Object arg0) throws Exception
{
if (arg0==null)
{
return null;
}
Class<?> cls = arg0.getClass();
JAXBContext context = JAXBContext.newInstance(cls);
Marshaller marshaller = context.createMarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Element root = doc.createElement("object");
root.setAttribute("cls", cls.getName());
marshaller.setProperty("jaxb.fragment", true);
marshaller.marshal(arg0, root);
return root;
}
public Element getFirstElement(Element element)
{
for (int i = 0; i < element.getChildNodes().getLength(); i++)
{
Node child = element.getChildNodes().item(i);
if (child.getNodeType() == Node.ELEMENT_NODE)
{
return (Element) child;
}
}
return null;
}
@Override
public Object unmarshal(Element element) throws Exception
{
if (element==null)
{
return null;
}
Element firstElement=getFirstElement(element);
if (firstElement==null)
{
return null;
}
String clzName = element.getAttribute("cls");
Class<?> cls = Class.forName(clzName);
JAXBContext context = JAXBContext.newInstance(cls);
Unmarshaller um = context.createUnmarshaller();
Object object = um.unmarshal(firstElement);
return object;
}
}
Finally attach the XmlAdapter to property through configuration or annotation.
No comments:
Post a Comment