Reputation: 505
Is there any way to decide at runtime which java class I would like to Unmarshall the XML into?
I tried in this way Unmarshall code -
public Object unmarshallXml(String xmlReq, String className)
{
String myClass = className+".class";
Object instances = null;
try {
JAXBContext jc = JAXBContext.newInstance( myClass );
Unmarshaller u = jc.createUnmarshaller();
StringBuffer xmlStr = new StringBuffer( xmlReq );
StringReader strReader = new StringReader( xmlStr.toString() );
StreamSource strSource = new StreamSource(strReader);
Object o = u.unmarshal( strSource );
} catch (JAXBException e) {
e.printStackTrace();
}
return instances;
}
but got this error -
" javax.xml.bind.JAXBException: "LookupInstances.class" doesnt contain ObjectFactory.class or jaxb.index"
Upvotes: 2
Views: 1769
Reputation: 505
Another solution can be -
public Object unmarshallXml(String xmlReq, Object obj) {
//ClientVariables instances = null;
Object o = null;
try {
JAXBContext jc = JAXBContext.newInstance(obj.getClass());
Unmarshaller u = jc.createUnmarshaller();
StringBuffer xmlStr = new StringBuffer(xmlReq);
StringReader strReader = new StringReader(xmlStr.toString());
StreamSource strSource = new StreamSource(strReader);
o = u.unmarshal(strSource);
//instances = (ClientVariables) o;
} catch (JAXBException e) {
e.printStackTrace();
}
return o;
}
Call can be made like this -
Utility util = new Utility();
LookupInstances instances = new LookupInstances();
instances = (LookupInstances) util.unmarshallXml(xmlReq, instances);
Upvotes: 0
Reputation: 148977
Can we decide the jaxb class at runtime during unmarshalling?
Yes, you just need to use one of the unmarshal
methods that take a Class
parameter.
Building the JAXBContext
Just because you want to unmarshal the class Foo
doesn't necessarily mean that you can just do JAXBContext.createContext(Foo.class)
. This is because there may be other classes that you need that can not be transitively reached from that class (ObjectFactory
) is a good example.
You can create the JAXBContext
on the package name, but that requires one of the following:
ObjectFactory
annotated with @XmlRegistry
to be located in that package, with enough pointers to your model to pull in all the necessary classes. If you generate your model from an XML Schema this will be done for you.ObjectFactory
class described above you can include a text file called jaxb.index
with a carriage return separated list of short class names for your model.JAXBContext
needs to be bootstrapped off a colon separated context path, where each package included meets one of the two conditions above.Upvotes: 3
Reputation: 7396
According to the API for Unmarshaller, you can call u.unmarshal(strSource, Foo.class)
and this will return a JAXBElement<Foo>
, on which you can call getValue()
to get the actual Foo
.
Also, read up on the usage of JAXBContext
while you're at it. You probably want to pass it a package and not a single class - but you didn't include enough context (ha ha) for me to be sure.
Upvotes: 2