javaxmlsoapjaxb

Is this SOAP envelope valid?


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?


Solution

  • From the comments above, I conclude that two things are odd:

    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.