I generated code using moxy for different xsd-Files: http://www.forum-datenaustausch.ch/generalinvoiceresponse_400.xsd and http://www.forum-datenaustausch.ch/xmlstandards_generelle_rechnung_beispiele_antwort_4.3_20100901.zip
I generated jaxb-classes for both xsd (using moxy). Then i tried unmarshal xml-files (genrated by eclipse) with this code:
public void tempTest() throws JAXBException{
JAXBContext jC = JAXBContext.newInstance(<package for corresponding type>.ResponseType.class);
jC.createUnmarshaller().unmarshal(ResponseTest.class.getResourceAsStream("/responses/generalInvoiceResponse_400.xml"));
}
With xml-File of 4.3-type (2nd link) this works fine but with xml of 400-type (1st link) i get this error:
Caused by: javax.xml.bind.UnmarshalException
- with linked exception:
[Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element {http://www.forum-datenaustausch.ch/de}response was not found in the project]
It seems to be a problem with the name-space. The name space is different but i can not see a relevant difference in generated code or generated xml - the name space is consistent. so what could cause this problem (where is the difference) and how to solve it?
small addition: i also tried to unmarshal xml marshaled with jaxb/moxy-code:
public void marshall() throws JAXBException, FileNotFoundException {
JAXBContext jC = JAXBContext.newInstance(ResponseType.class);
ObjectFactory of = new ObjectFactory();
jC.createMarshaller().marshal( of.createResponse(of.createResponseType()),new FileOutputStream("simpleresponse.xml"));
}
this creates an very simple xml:
<?xml version="1.0" encoding="UTF-8"?>
<response xmlns="http://www.forum-datenaustausch.ch/de"/>
unmarshaling this yields the same error.
When creating a JAXBContext
based on a model generated from an XML Schema you should always use the the newInstance
method that takes the package name. This will ensure that all the necessary bits are processed.
JAXBContext jC = JAXBContext.newInstance("ch.forum_datenaustausch.de");
When you use the JAXBContext.newInstance(Class...)
method the JAXB implementation is assuming that you started from Jav classes. Since the role of ObjectFactory
can be played by any class annotated with @XmlRegistry
the ObjectFactory
class generated from the XML schema will be automatically picked up. You could do the following, but I still recommend the above approach:
JAXBContext jC = JAXBContext.newInstance(ResponseType.class, ObjectFactory.class);
UPDATE
Thank you! but could you probably explain why it is working with one xsd and not with the other?
The schema where it "works" may have a global element with an anonymous type which causes an @XmlRootElement
annotation to be generated meaning the ObjectFactory
is not required. The other may have a global element with a named complex type which causes an @XmlElementDecl
annotation on an ObjectFactory
class to be generated.