In the interests of continuing experimentation of the validation stuff, I tweaked SampleApp1 in the following manner:
1. Purchase order type has a new element appended.
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
<xsd:element name="foo" type="fooType"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
2. fooType is defined as:
<xsd:complexType name="fooType">
<xsd:sequence>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="fee" minOccurs="0" maxOccurs="unbounded" type="xsd:string"/>
<xsd:element name="foo" minOccurs="0" maxOccurs="unbounded" type="fooType"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="fooName" type="xsd:string"/>
</xsd:complexType>
3. The po.xml file changed to:
<?xml version="1.0"?>
<purchaseOrder orderDate="1999-10-20">
<shipTo country="US">
<name>Alice Smith</name>
<street>123 Maple Street</street>
<city>Cambridge</city>
<state>MA</state>
<zip>12345</zip>
</shipTo>
<billTo country="US">
<name>Robert Smith</name>
<street>8 Oak Avenue</street>
<city>Cambridge</city>
<state>MA</state>
<zip>12345</zip>
</billTo>
<items>
<item partNum="242-NO">
<productName>Nosferatu - Special Edition (1929)</productName>
<quantity>5</quantity>
<USPrice>19.99</USPrice>
</item>
<item partNum="242-MU">
<productName>The Mummy (1959)</productName>
<quantity>3</quantity>
<USPrice>19.98</USPrice>
</item>
<item partNum="242-GZ">
<productName>Godzilla and Mothra: Battle for Earth/Godzilla vs. King Ghidora</productName>
<quantity>3</quantity>
<USPrice>27.95</USPrice>
</item>
</items>
<foo fooName="foo 1">
<fee>Fee 1</fee>
<foo fooName="foo 2">
<fee>Fee 2</fee>
<foo fooName="foo 3">
<fee>Fee 3 </fee>
</foo>
</foo>
</foo>
</purchaseOrder>
4. Main.java has the following modifications:
// display foo & fee, after the po is unmarshalled.
FooType foo = po.getFoo();
displayFoo( foo );
//method def
public static void displayFoo( FooType foo ) {
System.out.println("Foo name: "+foo.getFooName() );
List list = foo.getFeeOrFoo();
Iterator iter = list.iterator();
while( iter.hasNext() ){
Object object = iter.next();
if( object instanceof FooType ){
//recurse
displayFoo( (FooType) object );
} else {
System.out.println("Fee: "+( (FooTypeImpl.FeeImpl )object).getValue());
}
}
5. Build it and all is well. Classes are created & the output is what you'd expect.
6. Recall that the default unmarshaller validating behavior is OFF. Add the following before unmarshalling:
u.setValidating( true );
Build and I get:
DefaultValidationEventHandler: [ERROR]: unexpected attribute "fooName"
com.sun.msv.verifier.ValidityViolation: unexpected attribute "fooName"
at com.sun.msv.verifier.Verifier.onError(Verifier.java:319)
at com.sun.msv.verifier.Verifier.onError(Verifier.java:315)
at com.sun.msv.verifier.Verifier.feedAttribute(Verifier.java:259)
at com.sun.msv.verifier.Verifier.startElement(Verifier.java:204)
at com.sun.msv.verifier.VerifierFilter.startElement(VerifierFilter.java:97)
at org.iso_relax.verifier.impl.ForkContentHandler.startElement(Unknown Source)
at com.sun.xml.bind.validator.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:104)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:452)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:313)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1541)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:346)
at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:529)
at org.apache.xerces.parsers.DTDConfiguration.parse(DTDConfiguration.java:585)
at org.apache.xerces.parsers.XMLParser.parse(XMLParser.java:152)
at org.apache.xerces.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1142)
at com.sun.xml.bind.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:130)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:139)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:186)
at Main.main(Main.java:44)
--------------- linked to ------------------
javax.xml.bind.UnmarshalException
- with linked exception:
[com.sun.msv.verifier.ValidityViolation: unexpected attribute "fooName"]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:306)
at com.sun.xml.bind.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:134)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:139)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:186)
at Main.main(Main.java:44)
7. As a further step, turn validation on unmarshalling OFF, read in the content, then validate:
Validator validator = jc.createValidator();
validator.validate( po );
yields:
Running the sample application...
DefaultValidationEventHandler: [ERROR]: unexpected attribute "fooName"
javax.xml.bind.ValidationException
at com.sun.xml.bind.validator.ValidatorImpl.validate(ValidatorImpl.java:118)
at com.sun.xml.bind.validator.ValidatorImpl.validate(ValidatorImpl.java:94)
at Main.main(Main.java:48)
Is this consistent w/ the prior reports?
Am I doing something wrong?
Thank you,
David Halonen
Compuware
248.737.7300 ext 13578