I have an interesting situation where my XML editor (Oxygen, which uses Xerces XML processor) requires a prefix on the root tag, but my JAXB XML Marshaller (also Xercies-based) requires no prefix on the root tag. I'm trying to understand this situation.
First the 2 schema files:
ns1.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ns1.com"
xmlns="http://www.ns1.com"
xmlns:ns2="http://www.ns2.com"
elementFormDefault="unqualified"
attributeFormDefault="unqualified"
version="1.0" >
<xs:import namespace="http://www.ns2.com" schemaLocation="ns2.xsd"/>
<xs:element name="root">
<xs:complexType>
<xs:all>
<xs:element name="element1">
<xs:complexType>
<xs:all>
<xs:element name="element1a" type="NS1Type"/>
<xs:element name="element1b" type="ns2:NS2Type"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:simpleType name="NS1Type">
<xs:restriction base="xs:string">
<xs:enumeration value="VALUE_1"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
ns2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.ns2.com"
xmlns="http://www.ns2.com"
elementFormDefault="unqualified"
attributeFormDefault="unqualified"
version="1.0" >
<xs:complexType name="NS2Type">
<xs:all>
<xs:element name="value" type="xs:float" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:schema>
What the current release of Oxygen (16.1) requires what I'm going to call "Version 1"
Version 1
<?xml version="1.0" encoding="UTF-8"?>
<ns1:root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://www.ns1.com"
xsi:schemaLocation="http://www.ns1.com ../schema/ns1.xsd">
<element1>
<element1a>VALUE_1</element1a>
<element1b>
<value>4.5</value>
</element1b>
</element1>
</ns1:root>
If instead I remove the prefix like this example (Version 1):
Version 2
<?xml version="1.0" encoding="UTF-8"?>
<root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://www.ns1.com"
xsi:schemaLocation="http://www.ns1.com ../schema/ns1.xsd">
<element1>
<element1a>VALUE_1</element1a>
<element1b>
<value>4.5</value>
</element1b>
</element1>
</root>
Oxygen complains:
"[Xerces] cvc-elt.1.a: Cannot find the declaration of element 'root'."
JAXB on the other hands will only except Version 2. If I supply Version 1, I get this error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.ns1.com", local:"root"). Expected elements are <{}root>
The full stacktrace is:
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1063)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:150)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
Right now the JAXB marshaller and unmarshaller code is:
JAXBContext context = JAXBContext.newInstance(object.getClass());
javax.xml.bind.Marshaller marshaller = context.createMarshaller();
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Though I will soon be allowing Swagger Core to do the marshalling and unmarshalling and Swagger uses Jackson XML.
I need to figure out how to construct this XML (or configure JAXB) in a way that both my editor and my JAXB unmarshaller accept it
The problem is not prefixes but namespaces.
Your schemas have target namespaces but also
elementFormDefault="unqualified"
(are you sure you want this?). This means that global elements are qualified but local elements are not.So your
root
element is qualified and belongs to the namespacehttp://www.ns1.com
. So the Xerces error message is correct.The other question is, why does JAXB not recognize the namespace. A you did not post your Java code (please do) I have two theories:
package-info.java
which usually defines the prefix.By the way I would not call any JAXB implementation "Xerces-based".