JAXB unmarshal with declared type does not populate the resulting object with data
Your XML document does not match the namespace qualification that was defined in your mappings (see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html). You could leverage an XMLFilter
to apply a namespace to your XML document during the unmarshal operation.
import org.xml.sax.*;
import org.xml.sax.helpers.XMLFilterImpl;
public class NamespaceFilter extends XMLFilterImpl {
private static final String NAMESPACE = "htp://www.example.com/mdf/v4";
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(NAMESPACE, localName, qName);
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
super.startElement(NAMESPACE, localName, qName, atts);
}
}
Below is an example of how you would leverage the XMLFilter
during an unmarshal.
// Create the XMLFilter
XMLFilter filter = new NamespaceFilter();
// Set the parent XMLReader on the XMLFilter
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
filter.setParent(xr);
// Set UnmarshallerHandler as ContentHandler on XMLFilter
Unmarshaller unmarshaller = jc.createUnmarshaller();
UnmarshallerHandler unmarshallerHandler = unmarshaller
.getUnmarshallerHandler();
filter.setContentHandler(unmarshallerHandler);
// Parse the XML
InputSource xml = new InputSource("input.xml");
filter.parse(xml);
Object result = unmarshallerHandler.getResult();
For More Information
Slacky
Updated on June 05, 2022Comments
-
Slacky almost 2 years
I am trying to unmarshal a given XML:
<FHcomment> <TX>rewriting of file</TX> <tool_id>toolA</tool_id> <tool_vendor>Company</tool_vendor> <tool_version>1.7.36.0</tool_version> </FHcomment>
The schema has already been compiled to JAXB classes, see here:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "tx", "toolId", "toolVendor", "toolVersion", "userName", "commonProperties", "extensions" }) @XmlRootElement(name = "FHcomment") public class FHcomment { @XmlElement(name = "TX", required = true) protected TX tx; @XmlElement(name = "tool_id", required = true) protected BaseName toolId; @XmlElement(name = "tool_vendor", required = true) protected BaseName toolVendor; @XmlElement(name = "tool_version", required = true) protected BaseVersion toolVersion; @XmlElement(name = "user_name") protected BaseName userName; @XmlElement(name = "common_properties") protected CommonPropertiesType commonProperties; protected ExtensionsType extensions; @XmlAnyAttribute private Map<QName, String> otherAttributes = new HashMap<QName, String>(); ..... /* * GETTERS and SETTERS for the fields have been removed here */ ..... }
My code to unmarshal the XML is as follows:
JAXBContext jc = JAXBContext.newInstance(FHcomment.class); String s = "<FHcomment>....</Fhcomment>"; Unmarshaller unmarshaller = jc.createUnmarshaller(); XMLInputFactory fac = XMLInputFactory.newFactory(); XMLStreamReader xsr = fac.createXMLStreamReader(new StringReader(s)); JAXBElement<FHcomment> foo = unmarshaller.unmarshal(xsr, FHcomment.class); FHcomment val = foo.getValue();
Problem: The resulting FHcomment object does not contain the children elements of FHcomment. All are null which is not the desired result.
How can I tell JAXB to completely unmarshal the given XML into an object?
EDIT: After adding a ValidationHandler to the Unmsarshaller, I got closer to the problem:
unexpected element (uri:"", local:"TX"). Expected elements are <{htp://www.example.com/mdf/v4}tool_id>,<{htp://www.example.com/mdf/v4}TX>,<{htp://www.www.example.com/mdf/v4}common_properties>,<{htp://www.example.com/mdf/v4}tool_version>,<{htp://www.example.com/mdf/v4}extensions>,<{htp://www.www.example.com/mdf/v4}tool_vendor>,<{htp://www.www.example.com/mdf/v4}user_name>
unexpected element (uri:"", local:"tool_id"). Expected elements are....
It turns out JAXB does not like the fact that the provided XML does not contain namespace information.. So how do I tell the unmarshaller to ignore the namespaces?
EDIT2:
After some more research I could not find a way to trick JAXB into working without namespace verification. I used the tutorial at http://cooljavablogs.blogspot.de/2008/08/how-to-instruct-jaxb-to-ignore.html to circumvent my problem. Not a nice solution but the best at hand...
-
Slacky almost 11 yearsSadly the classes are generated and any modification will be lost after an update to the schema definitions.
-
Balint Bako almost 11 yearsThen update the xml... You need make BaseName and TX xml-serializable too, by the way. If you use a custom class as a property in a JAXB class, that is a "complex type" in the XSD.