I have an issue using JaxB in Netbeans 7.1.2.
I have auto-generated my classes from a schema using JaxB (New JaxB Binding). I am creating the object that will be serialized to an XML string using the Marshaller and then back to a new object instance from the XML String. However, I get the following exception:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.somewhere.com/some/path", local:"MyQueryComplexTypeQuery"). Expected elements are (none)
The marshalling/serializing to XML string works fine. It's when it is unmarshalled/deserialized that is causing the issue.
I am using the following code to build the object and marshal it to an XML string:
// build the object
ObjectFactory of = new ObjectFactory();
MyQueryComplexType oaaqc = of.createMyQueryComplexType();
oaaqc.setField1("edit");
oaaqc.setField2("net");
oaaqc.setField3("24");
JAXBElement<MyQueryComplexType> createMyQueryComplexType = of.createMyQueryComplexTypeQuery(oaaqc);
// serialise to xml
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
Marshaller m = context.createMarshaller();
m.marshal(createMyQueryComplexType, writer);
// output string to console
String theXML = writer.toString();
System.out.println(theXML);
This produces the following XML (formatted) in the console:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyQueryComplexTypeQuery xmlns="http://www.somewhere.com/some/path">
<Field1>edit</Field1>
<Field2>net</Field2>
<Field3>24</Field3>
</MyQueryComplexTypeQuery>
Now I come to deserialize/unmarshal the string to a new instance MyQueryComplexType with the following code:
Unmarshaller u = context.createUnmarshaller();
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
In the auto generated package-info.java it has the following contents:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.somewhere.com/some/path", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package MyProject.SomeNamespace.MyQuery;
I thought the simple process of object -> string -> object would work. This is the first time I've used JaxB (so be gentle). I have seen other posts mentioning the namespaces, and everything looks ok to me. I've auto generated the classes from the schema, constructed the object, marshalled to xml string. I thought simply reversing the process for unmarshal would be similar.
The actual exception is thrown on line:
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
I thought I was doing the unmarshalling from string to object would be simple. I don't know if I am doing something wrong or missing something. I hope you guys can shed some light or open my eyes.
I have cut down the code to simplify what is in my app that causes the error. Namespaces have been changed to protect the identity of things on the web.
Any thoughts?
Thanks
Andez
To unmarshal an xml string into a JAXB object, you will need to create an Unmarshaller from the JAXBContext, then call the unmarshal() method with a source/reader and the expected root object.
We can convert Object to String in java using toString() method of Object class or String. valueOf(object) method. You can convert any object to String in java whether it is user-defined class, StringBuilder, StringBuffer or anything else.
To read XML, first get the JAXBContext . It is entry point to the JAXB API and provides methods to unmarshal, marshal and validate operations. Now get the Unmarshaller instance from JAXBContext . It's unmarshal() method unmarshal XML data from the specified XML and return the resulting content tree.
Creating the JAXBContext
For JAXB models that are generated from an XML schema you could create the JAXBContext
on the package name rather than on a particular class:
JAXBContext context = JAXBContext.newInstance("your.package.name");
Not:
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
This will ensure that the ObjectFactory
class that contains the @XmlElementDecl
annotations is processed correctly which is what is missing from your use case.
Unmarshal Operation
Note that during your marshal operation you needed to wrap your instance of MyQueryComplexType
in a JAXBElement
? This is because MyQueryComplexType
was not annotated with @XmlRootElement
and the root element information needed to come from the JAXBElement
. This means that when you do the unmarshal operation you will get a JAXBElement
back as well.
JAXBElement<MyQueryComplexTypeQuery> o = (JAXBElement<MyQueryComplexType>) u.unmarshal(new StringReader(theXML));
Not:
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
For More Information
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With