views:

338

answers:

2

Hello,

I have a JAXB class generation problem I was hoping to get some help with. Here's the part of the XML that is the source of my problem...

Code:

<xs:complexType name="IDType"> 
<xs:choice minOccurs="0" maxOccurs="2"> 
  <xs:element name="DriversLicense"    minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="SSN"        minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="CompanyID"       minOccurs="0" maxOccurs="1" type="an..35" /> 
  </xs:choice> 
</xs:complexType> 
<xs:simpleType name="an..35"> 
  <xs:restriction base="an"> 
    <xs:maxLength value="35" /> 
  </xs:restriction> 
</xs:simpleType> 

<xs:simpleType name="an"> 
   <xs:restriction base="xs:string"> 
     <xs:pattern value="[ !-~]*" /> 
   </xs:restriction> 
</xs:simpleType>

...now this will generate JAXBElement types due the the "choice" with a "maxOccurs > 1" . I want to avoid those, so I did that by modifying the code to use a "Wrapper" element and move the maxOccurs up to a sequence tag as follows...

Code: 
<xs:complexType name="IDType"> 
<xs:sequence maxOccurs="2"> 
  <xs:element name=Wrapper>
  <xs:complexType>
  <xs:choice> 
  <xs:element name="DriversLicense"    minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="SSN"        minOccurs="0" maxOccurs="1" type="an..35" /> 
    <xs:element name="CompanyID"       minOccurs="0" maxOccurs="1" type="an..35" /> 
  </xs:choice>
  </xs:complexType>
  </xs:element>
</xs:sequence> 
</xs:complexType>

<xs:simpleType name="an..35"> 
  <xs:restriction base="an"> 
    <xs:maxLength value="35" /> 
  </xs:restriction> 
</xs:simpleType> 

<xs:simpleType name="an"> 
   <xs:restriction base="xs:string"> 
     <xs:pattern value="[ !-~]*" /> 
   </xs:restriction> 
</xs:simpleType> 

For class generating, looks like it works great - the JAXB element is replaced with a list of wrappers as String (i.e. List ) and compiles fine.

However, when I unmarshall the actual XML data into the generated classes the data in the wrapper class is not populated - yet JAXB does not throw an exception.

My question is: Do I need to change the schema a different way to make this work? Or is there something I can add/change/delete to the generated code or annotations?

Appreciate any help you can offer!

Thanks.

+2  A: 

Not a bad idea, but note the following: according to your schema, it is perfectly legal that your "Wrapper" element has no content. It contains a choice of optional items.

Secondly, you may not have schema validation on; then JAXB will not complain if your documents are broken. If you want to turn on schema validation, get an Unmarshaller and initialise like this:

 unmarshaller.setValidating(true);
 SchemaFactory sf = SchemaFactory.newInstance(
    javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
 Schema schema = sf.newSchema(new File("my-schema.xsd"));
 unmarshaller.setSchema(schema);
xcut
A: 

Thanks for the prompt response. I appreciate it.

Yes, I do have a validator and that is where I caught it - just as you said. However, in debug mode, after unmarshalling XML that had two instances if the IDType's wrapper (i.e. DriversLicense and SSN in this case), I looked at the classes and noticed they were truly not populated.

Thus, even though the Wrapper class was generated, unmarshalling still failed when it shouldn't have.

Do you have any ideas why? Any suggestions in changing either the XML or any bindings customizations? Thanks again!

Please don't post your comments as if they were answers, add them as comments to the answer you're responding to.
skaffman