I am using JAXB to process XML input wrapped in a SOAP 1.2. However, I am getting an exception during unmarshaling:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"d2LogicalModel"). Expected elements are <{http://datex2.eu/schema/2/2_0}d2LogicalModel>
This is the XML code:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<d2LogicalModel xmlns:ns2="http://datex2.eu/schema/2/2_0" modelBaseVersion="2">
<ns2:exchange>
<ns2:supplierIdentification>
<ns2:country>fr</ns2:country>
<ns2:nationalIdentifier>Tipi</ns2:nationalIdentifier>
</ns2:supplierIdentification>
<ns2:subscription>
<ns2:operatingMode>operatingMode3</ns2:operatingMode>
<ns2:subscriptionStartTime>2025-09-05T15:06:26.906+02:00</ns2:subscriptionStartTime>
<ns2:subscriptionState>active</ns2:subscriptionState>
<ns2:subscriptionStopTime>2025-09-05T15:06:26.906+02:00</ns2:subscriptionStopTime>
<ns2:updateMethod>snapshot</ns2:updateMethod>
<ns2:target>
<ns2:address/>
<ns2:protocol/>
</ns2:target>
</ns2:subscription>
</ns2:exchange>
<ns2:payloadPublication xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:SituationPublication" lang="fr">
<feedType xmlns="http://datex2.eu/schema/2/2_0">2736545</feedType>
<ns2:publicationTime>2025-09-05T15:06:26.906+02:00</ns2:publicationTime>
<ns2:publicationCreator>
<ns2:country>fr</ns2:country>
<ns2:nationalIdentifier>Tipi</ns2:nationalIdentifier>
</ns2:publicationCreator>
<!-- several ms2:situation elements omitted for brevity -->
</ns2:payloadPublication>
</d2LogicalModel>
</soap:Body>
</soap:Envelope>
And the code to unmarshal it:
JAXBElement<D2LogicalModel> root;
JAXBContext jc = JAXBContext.newInstance(D2LogicalModel.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMessage = mf.createMessage(null, is);
SOAPBody body = soapMessage.getSOAPBody();
root = (JAXBElement<D2LogicalModel>)unmarshaller.unmarshal(body.getFirstChild());
D2LogicalModel d2lm = root.getValue();
return d2lm;
D2LogicalModel
was auto-generated from the Datex-II XML schema found at https://docs.datex2.eu/downloads/modelv23/#datex-ii-xml-schema-23 using
xjc -no-header -d schemas -b xsd/binding.xml xsd
Class declaration is as follows:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "D2LogicalModel", propOrder = {
"exchange",
"payloadPublication",
"d2LogicalModelExtension"
})
public class D2LogicalModel {
// body omitted
}
The helpful AI assistant tells me that the d2LogicalModel
element is missing xmlns="http://datex2.eu/schema/2/2_0"
. Indeed, when I add xmlns
alongside xmlns:ns2
in the XML input, it unmarshals with no issues.
However, it seems strange that I’d be the first to notice an error in a resource published by a national road network operator. Also, having to add almost the same namespace definition twice seems odd to me.
Is this really an error in the input, or am I doing something wrong in my unmarshaling code?
From the comments above, I conclude that two things are odd:
D2LogicalModel
and children) spread across two namespaces (empty namespace and ns2
)As soon as I either add a definition for the empty namespace (in D2LogicalModel
) or prefix the d2LogicalModel
tag with ns2:
, the document unmarshals with no issues.
A workaround I have found is to change the call to unmarshal
, specifying the target class explicitly:
root = (JAXBElement<D2LogicalModel>)unmarshaller.unmarshal(body.getFirstChild(), D2LogicalModel.class);
As long as the anomalies affect only the root element of the payload (as is the case here), this modification causes the XML data to unmarshal as-is with no issues.