Initially my code was throwing the following exception:
Exception
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://net.igorkromin/", local:"MyComplexType"). Expected elements are (none)
So that meant that the unmarshaller didn't recognise any valid elements in my XML string that I was trying to unmarshal. I checked the JAXB Context and it definitely had the complex type I was after so it was something else I was doing wrong.
Lets take a step back and look at the schema, my complex type, MyComplexType, was defined as:
XSD
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://net.igorkromin/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://net.igorkromin/" elementFormDefault="qualified">
...
<xsd:complexType name="MyComplexType">
<xsd:sequence>
...
</xsd:sequence>
</xsd:complexType>
...
That resulted in a JAXB generated class that looked like:
Java Class
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "MyComplexType",
propOrder = {...}
)
public class MyComplexType {
...
}
So, no XmlRootElement annotation. That's because it was a complex type and not an element of that type. That should have been obvious right away, but I missed it initially. Luckily there was a simple way around it. All I had to do was tell JAXB what complex type I was expecting and wrap the XML fragment as a Source or specifically StreamSource.
So the code that would achieve that looked something like...
Java
String xmlString =
"< MyComplexType xmlns=\"http://net.igorkromin/\">\n" +
" ..." +
"</MyComplexType >";
JAXBContext ctx = JAXBContext.newInstance(MyComplexType.class);
Unmarshaller u = ctx.createUnmarshaller();
ByteArrayInputStream bais = new ByteArrayInputStream(xmlString.getBytes());
Source source = new StreamSource(bais);
JAXBElement<MyComplexType> mct = u.unmarshal(source, MyComplexType.class);
That worked like a charm and I could then get my unmarshalled complex type instance from the JAXBElement instance.
-i