Cannot unmarshal document if default namespace is used

I created a repo that shows my problem: https://github.com/Waxolunist/stackoverflow.34392476

I am trying to untie a simple XML document:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <for:document xmlns:for="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx"> <Export xmlns="urn:adcubum:Syrius"> <ExportInhalt/> <ExportKopf> <Quelle>lokal</Quelle> </ExportKopf> <SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</SchemaVersion> </Export> </for:document> 

This is the document I get from the following code:

  Document document = new Document(); Export export = new Export(); ExportKopf exportKopf = new ExportKopf(); exportKopf.setQuelle("lokal"); export.setExportKopf(exportKopf); ExportInhalt exportInhalt = new ExportInhalt(); export.setExportInhalt(exportInhalt); export.setSchemaVersion("bec811a9807a8c8da403d70b9b5e22ad"); document.setExport(export); JAXBContext jaxbContext = JAXBContext.newInstance(Document.class); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(document, System.out); 

The document is as follows:

 @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "document", namespace = "http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx") public class Document { @XmlElement(name = "Export", namespace = "urn:adcubum:Syrius") private vo.dom.common_service.modul_bl.syrius.Export export; } 

package-info.java

 @XmlSchema( namespace = "urn:adcubum:Syrius", xmlns = { @XmlNs(prefix = "for", namespaceURI = "http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx"), @XmlNs(prefix = "", namespaceURI = "urn:adcubum:Syrius") }, elementFormDefault = XmlNsForm.UNQUALIFIED) 

When I try to unmount it, I do not receive data:

  JAXBContext jaxbContext = JAXBContext.newInstance(Document.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); InputStream is = this.getClass().getResourceAsStream("/requests/document_simple3.xml"); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader xmlsr = factory.createXMLStreamReader(is); Document document = unmarshaller.unmarshal(xmlsr, Document.class).getValue(); 

ExportKopf and ExportInhalt return null.

Instead, xml works. The only difference is the namespace prefix:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <for:document xmlns:for="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx"> <ns3:Export xmlns:ns3="urn:adcubum:Syrius"> <ExportInhalt/> <ExportKopf> <Quelle>lokal</Quelle> </ExportKopf> <SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</SchemaVersion> </ns3:Export> </for:document> 

I am using eclipselink moxy.

What do I need to change to work with a marshaled document.

+5
source share
2 answers

I think it is always a good idea to see the real XSD scheme of your mapping when something strange happens in JAXB. You can easily do this with the following code.

 JAXBContext jaxbContext = JAXBContext.newInstance(Document.class); jaxbContext.generateSchema(new SchemaOutputResolver() { @Override public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { StreamResult streamResult = new StreamResult(new PrintWriter(System.err) { @Override public void close() { } }); streamResult.setSystemId(suggestedFileName); return streamResult; } }); 

This will print the circuit (s) that should reflect your JAXB model (you can use a different writer to write them to a file). XSD files are usually very revealing about these issues. I think the problem in your case is the @XmlSchema mapping. You should try using elementFormDefault = XmlNsForm.QUALIFIED instead. It is always useful to use QUALIFIED whenever you work with multiple namespaces in your mapping.

EDIT : while the main problem with your JAXB mapping was the wrong and / or missing value for elementFormDefault , there were other things that needed to be fixed for your repo code to work.

  • There was no namespace declaration in the Export element in Document (from your example, the Document and Export elements are parts of different namespaces)
  • missing elementFormDefault = XmlNsForm.QUALIFIED from Export package
  • incorrect namespace value for the main @XmlSchema annotation package (there was urn:stackoverflow:exportnamespace instead of urn:stackoverflow:documentnamespace in which the Document element should be)
  • incorrect import for jdk_jaxb/UnmarshallerTest.java - it imported model.eclipselink.Document instead of model.sun.Document
+4
source

EDIT: here's the updated code https://github.com/MojoJojo/stackoverflow.34392476

Ok, here is a working version with all moxy_jaxb testing. Since you said you were using moxy, I did not account for the changes for model.sun packages. *. If you understand the concept below, you can easily fix it yourself.

First I cleared the namespace declarations in your mode. * packages. In most cases, declarations and bindings inside package-info.java are enough. Announcing them again and again in packages, entities, and fields will add complexity and undesirable behavior. See this link for more details. There is no need to re-declare them separately for the models / entities themselves, unless there is good reason for this. Further, the xml test itself was a bit broken. Fixed test xml with the necessary prefixes, where necessary:

Firstly, model.eclipselink.Document.java

 @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "document") public class Document { @XmlElement(name = "Export", namespace="urn:adcubum:Syrius") private Export export; public Export getExport() { return export; } public void setExport(Export export) { this.export = export; } } 

model.eclipselink.package-info.java:

 @XmlSchema(namespace = "http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx", elementFormDefault = XmlNsForm.QUALIFIED) package model.eclipselink; import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.XmlSchema; 

Similar refactoring on model.eclipselink.export.packageinfo.java:

 @XmlSchema(namespace = "urn:adcubum:Syrius", elementFormDefault = XmlNsForm.QUALIFIED) package model.eclipselink.export; import javax.xml.bind.annotation.XmlNs; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.Xml 

And on Export.java:

 package model.eclipselink.export; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlElementNillable; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Export") @XmlType(name = "Export", propOrder = { "exportInhalt", "exportKopf", "schemaVersion" }) public class Export { @XmlElement(name = "ExportKopf", required = true) private ExportKopf exportKopf; @XmlElement(name = "ExportInhalt", required = true) private ExportInhalt exportInhalt; @XmlElement(name = "SchemaVersion", required = true) private String schemaVersion; public ExportKopf getExportKopf() { return exportKopf; } public void setExportKopf(ExportKopf exportKopf) { this.exportKopf = exportKopf; } public ExportInhalt getExportInhalt() { return exportInhalt; } public void setExportInhalt(ExportInhalt exportInhalt) { this.exportInhalt = exportInhalt; } public String getSchemaVersion() { return schemaVersion; } public void setSchemaVersion(String schemaVersion) { this.schemaVersion = schemaVersion; } } 

And a few settings for your xml files for prefixes. Here document_prefix.xml

 <?xml version="1.0" encoding="UTF-8"?> <for:document xmlns:for="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx"> <ns1:Export xmlns:ns1="urn:adcubum:Syrius"> <ns1:ExportKopf> <ns1:Quelle>lokal</ns1:Quelle> </ns1:ExportKopf> <ns1:ExportInhalt/> <ns1:SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</ns1:SchemaVersion> </ns1:Export> </for:document> 

document.xml:

 <?xml version="1.0" encoding="UTF-8"?> <for:document xmlns:for="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx" xmlns="urn:adcubum:Syrius"> <Export> <ExportKopf> <Quelle>lokal</Quelle> </ExportKopf> <ExportInhalt /> <SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</SchemaVersion> </Export> </for:document> 

and document_realnamespace.xml (I don't know what the purpose of this file is):

 <?xml version="1.0" encoding="UTF-8"?> <for:document xmlns:ns1="urn:adcubum:Syrius" xmlns:for="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrenderer/forwktbx"> <ns1:Export> <ns1:ExportKopf> <ns1:Quelle>lokal</ns1:Quelle> </ns1:ExportKopf> <ns1:ExportInhalt/> <ns1:SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</ns1:SchemaVersion> </ns1:Export> </for:document> 

And you run mvn clean test:

 Running moxy_jaxb.MarshallerTest Context class: class org.eclipse.persistence.jaxb.JAXBContext <?xml version="1.0" encoding="UTF-8"?> <document xmlns="http://www.adcubum.com/wsdl/global/callout/syrius/modul_bl/doc/service/documentrend erer/forwktbx" xmlns:ns0="urn:adcubum:Syrius"> <ns0:Export> <ns0:ExportInhalt/> <ns0:ExportKopf> <ns0:Quelle>lokal</ns0:Quelle> </ns0:ExportKopf> <ns0:SchemaVersion>bec811a9807a8c8da403d70b9b5e22ad</ns0:SchemaVersion> </ns0:Export> </document> Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 sec Running moxy_jaxb.UnmarshallerTest Context class: class org.eclipse.persistence.jaxb.JAXBContext lokal Context class: class org.eclipse.persistence.jaxb.JAXBContext lokal Context class: class org.eclipse.persistence.jaxb.JAXBContext lokal Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.033 sec 
+1
source

Source: https://habr.com/ru/post/1238814/


All Articles