users@jaxb.java.net

Unexpect Element vs. undefined attribute

From: Gerry Plummer <gerry_at_TELOQUENT.COM>
Date: Wed, 19 Mar 2003 09:43:09 -0700

Hi -

I have some questions about the JAXB RI unmarshaller.

1. Is there any way to handle a validation event from the unmarshaller,
which can consume and return "true" on an "unexpected element" ERROR
such that unmarshalling can continue? I.e. is there any way to cause the
unmarshaller to just ignore extra elements?

It seems not, and that I'm going to have to insert wildcards into my
schema at points where such extensions (additional elements) may be
required. This is an issue of the versioning strategy for an XML
messaging interface.that may require extension in the future.


2. However, it seems that the unmarshaller _does_ ignore undefined
attributes. Is this a bug? Or is it a feature? Can it be depended on?

Examples below.

 -gerry plummer


------------------------------------------------------------------------
Relevant schema fragments

<xs:complexType name="ConnectType">
 <xs:sequence>
  <xs:element name="DeviceName" type="xs:NMTOKEN"
              nillable="true" minOccurs="0"/>
  <xs:element name="Provider" type="ProviderType"/>
  <xs:element name="SchemaVersion" type="xs:int"/>
  <xs:element name="ProtocolVersion" type="xs:int"/>
  <xs:element name="HeartbeatPeriod" type="xs:int"/>

  <xs:any namespace="##any" processContents="strict"
          minOccurs="0" maxOccurs="unbounded">
      <xs:annotation><xs:appinfo>
       <jxb:property name="Extension"/>
   </xs:appinfo></xs:annotation>
  </xs:any>

 </xs:sequence>
</xs:complexType>


<xs:complexType name="ConnectResponseType">
 <xs:sequence>
  <xs:element name="DeviceName" type="xs:NMTOKEN"
              nillable="true" minOccurs="0"/>
  <xs:element name="SchemaVersion" type="xs:int"/>
  <xs:element name="ProtocolVersion" type="xs:int"/>
  <xs:element name="Provider" type="ProviderType"/>
 </xs:sequence>
</xs:complexType>

------------------------------------------------------------------------
Example XML documents:

1. This one unmarshals correctly:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<TQLinkMessage>
  <Source>
    <DeviceID>100</DeviceID>
    <ServiceID>52</ServiceID>
  </Source>
  <Destination>
    <DeviceID>999</DeviceID>
    <ServiceID>22</ServiceID>
  </Destination>
  <SessionMessage>
    <Connect>
      <DeviceName>TestServer</DeviceName>
   <Provider>
     <ProviderName>TQTest</ProviderName>
     <ContactType>0</ContactType>
   </Provider>
   <SchemaVersion>1</SchemaVersion>
   <ProtocolVersion>1</ProtocolVersion>
   <HeartbeatPeriod>0</HeartbeatPeriod>
    </Connect>
  </SessionMessage>
</TQLinkMessage>


2. This also unmarshals correctly.
The extra element <Foozle> is seen as a wildcard element:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<TQLinkMessage>
  <Source>
    <DeviceID>100</DeviceID>
    <ServiceID>52</ServiceID>
  </Source>
  <Destination>
    <DeviceID>999</DeviceID>
    <ServiceID>22</ServiceID>
  </Destination>
  <SessionMessage>
    <Connect>
      <DeviceName>TestServer</DeviceName>
   <Provider>
     <ProviderName>TQTest</ProviderName>
     <ContactType>0</ContactType>
   </Provider>
   <SchemaVersion>1</SchemaVersion>
   <ProtocolVersion>1</ProtocolVersion>
   <HeartbeatPeriod>0</HeartbeatPeriod>
      <Foozle>Hunyoc</Foozle>
    </Connect>
  </SessionMessage>
</TQLinkMessage>


3. This example also has an extra <Foozle> element. There being no
wildcard element defined for ConnectResp, this fails to unmarshal.
Even if I use a custom handler, test for non-fatal error (which this
is not) and return "true" to indicate continuation, the unmarshaller
aborts. (BTW: Note that the locator's offset seems useless!)

Test file: TestXML/tqlsession-connectresp-foozlelem.xml
**ERROR: Unexpected element {}:Foozle at offset -1
ERROR: Failed to unmarshall XML message
    [javax.xml.bind.UnmarshalException: Unexpected element {}:Foozle]
No message

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<TQLinkMessage>
  <Source>
    <DeviceID>999</DeviceID>
    <ServiceID>22</ServiceID>
  </Source>
  <Destination>
    <DeviceID>100</DeviceID>
    <ServiceID>52</ServiceID>
  </Destination>
  <SessionMessage>
    <ConnectResp>
      <DeviceName>TestArrPt</DeviceName>
   <SchemaVersion>1</SchemaVersion>
   <ProtocolVersion>1</ProtocolVersion>
   <Provider>
     <ProviderName>TQTest</ProviderName>
     <ContactType>1</ContactType>
     <ContactType>2</ContactType>
     <ContactType>16</ContactType>
   </Provider>
      <Foozle>Hunyoc</Foozle>
    </ConnectResp>
  </SessionMessage>
</TQLinkMessage>


4. This example document has an attribute extattr with value
"strange", for element <Provider>. This attribute is not defined by the
schema. It produces no error, however:

Test file: TestXML/tqlsession-connectresp-extattr.xml
+++++
TQLinkMessage:
Source: DeviceID: 999, ServiceID: 22
Destination: DeviceID: 100, ServiceID: 52
Session Connect Response message:
DeviceName: TestArrPt
Provider: ProviderName: TQTest, ContactTypes: [1,2,16]
SchemaVersion: 1, ProtocolVersion: 1
-----

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<TQLinkMessage>
  <Source>
    <DeviceID>999</DeviceID>
    <ServiceID>22</ServiceID>
  </Source>
  <Destination>
    <DeviceID>100</DeviceID>
    <ServiceID>52</ServiceID>
  </Destination>
  <SessionMessage>
    <ConnectResp>
      <DeviceName>TestArrPt</DeviceName>
   <SchemaVersion>1</SchemaVersion>
   <ProtocolVersion>1</ProtocolVersion>
   <Provider extattr="strange">
     <ProviderName>TQTest</ProviderName>
     <ContactType>1</ContactType>
     <ContactType>2</ContactType>
     <ContactType>16</ContactType>
   </Provider>
    </ConnectResp>
  </SessionMessage>
</TQLinkMessage>