-
1. Re: How to force strict validation?
aloubyansky Feb 26, 2008 4:24 AM (in response to rob.stryker)Strict means that every XML component must be represented in the Java model. I don't see why your test should fail.
-
2. Re: How to force strict validation?
aloubyansky Feb 26, 2008 4:26 AM (in response to rob.stryker)I meant, I don't see why there should be an exception as you expect.
-
3. Re: How to force strict validation?
rob.stryker Feb 26, 2008 4:12 PM (in response to rob.stryker)I'm sorry, Alexey. I forgot the most important part:
<?xml version="1.0" encoding="UTF-8"?> <!-- Should Fail to validate --> <garbageRoot> </garbageRoot>
That's the data file I'm reading which is clearly missing the REQUIRED attribute "name".<xsd:attribute name="name" type="xsd:string" use="required" />
So this *should* fail, yes? It's not failing. =/ -
4. Re: How to force strict validation?
rob.stryker Feb 26, 2008 4:14 PM (in response to rob.stryker)The version I'm using in JBoss Tools / JBDS is "jbossxb-1.0.1.TEST.jar", which was found somewhere in our repository (internal?) but has been used in the tooling for a while. Should I be using a newer version?
-
5. Re: How to force strict validation?
rob.stryker Feb 26, 2008 4:26 PM (in response to rob.stryker)Ok clearly some of my text didn't post. Let me try that again with obvious changes
[garbageRoot]
[/garbageRoot] -
6. Re: How to force strict validation?
aloubyansky Feb 27, 2008 6:35 AM (in response to rob.stryker)I think, you should use [ code ] [ /code ] tags for XML.
This is not the strictness that is supposed to be enforced by strictSchema.
It's a bit confusing. This is XML validation issue. And is supposed to be the responsibility of the XML parser. Although, XB validates model groups (order of elements) to some extent.
StrictSchema would affect unmarshalling if for example XbGarbageRoot didn't have name property and the name attribute was present in the XML. -
7. Re: How to force strict validation?
rob.stryker Feb 27, 2008 4:09 PM (in response to rob.stryker)So is there any part of jboss xb which *can* validate as such and fail when a required attribute is *not* present?
-
8. Re: How to force strict validation?
aloubyansky Feb 27, 2008 4:16 PM (in response to rob.stryker)You should be able to configure the underlying xml parser to validate the xml. There are methods in the Unmarshaller to do that: setValidation() and setFeature(). In addition you should make sure that the XML schema can be resolved by the xml parser, so it knows what to validate against.
-
9. Re: How to force strict validation?
aloubyansky Feb 27, 2008 4:17 PM (in response to rob.stryker)You may need to configure EntityResolver for that or set your own.
-
10. Re: How to force strict validation?
adrian.brock Feb 27, 2008 4:48 PM (in response to rob.stryker)"rob.stryker@jboss.com" wrote:
So is there any part of jboss xb which *can* validate as such and fail when a required attribute is *not* present?
It's not really the job of xml binding to validate the schema/dtd.
e.g. compare the JAXB spec.
The binding framework has been revised significantly since JAXB 1.0.
Significant changes include:
...
• unmarshal/marshal time validation deferring to JAXP 1.3 validation.
If you want validation, configure the xml parser to do it (which are options
on the unmarshaller).
Example from the deployers:
http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbossas/projects/microcontainer/trunk/deployers-vfs-spi/src/main/org/jboss/deployers/vfs/spi/deployer/SchemaResolverDeployer.java?revision=69994&view=markup
The JAXP parser needs to be able to resolve the schema document
to actually do the validation as Alex says. :-) -
11. Re: How to force strict validation?
rob.stryker Feb 28, 2008 8:43 PM (in response to rob.stryker)Thanks for the replies:
Just setting validation and schema validation to true did not accomplish what I needed it to do. I still was unable to access the parser to set the properties needed. I ended up cloning UnmarshallerImpl and making the getParser() method public (rather than package private) to do what I needed it to.public class ParseTest extends TestCase { private static final String SCHEMA = "/home/rob/apps/eclipse/workspaces/work/garbage/src/schema.xsd"; private static final String DATA = "/home/rob/apps/eclipse/workspaces/work/garbage/data/test.xml"; public void testABC() { try { File f = new File(SCHEMA); InputStream stream = new FileInputStream(f); SchemaBinding binding = XsdBinder.bind(stream, "UTF-8", (String)null); stream.close(); binding.setStrictSchema(true); UnmarshallerImpl unmarshaller = new UnmarshallerImpl(); String schemaLocation = new File("/home/rob/apps/eclipse/workspaces/work/garbage/src/schema.xsd").toURI().toURL().toExternalForm(); unmarshaller.setValidation(true); unmarshaller.getParser().setFeature("http://apache.org/xml/features/validation/schema", true); unmarshaller.getParser().setProperty("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", schemaLocation); FileInputStream dataStream = new FileInputStream(new File(DATA)); Object xmlObject = unmarshaller.unmarshal(dataStream, binding); System.out.println("object is " + xmlObject); } catch( Exception e ) { // GOOD! I want XB to fail! return; } fail("data file should not have validated!"); } }
Now I'm just looking via APIs to find a similar way to enforce strict validation when writing / marshalling the files as well ;)
Again, thanks for the help. -
12. Re: How to force strict validation?
rob.stryker Feb 28, 2008 10:26 PM (in response to rob.stryker)Ok... well... for writing a file, it's obvious to me that JBoss XB cannot validate the object conforms to schema until either a) its done marshalling the object, or b) doing it while serializing.
I'm currently using XercesXSMarshaller to serialize my object, and after tracing through, it doesn't seem to check any data structure at all to see if any required attributes are missing.
I notice that around line 492 in XercesXSMarshaller, it gets a list of attributes that can be there, but after browsing that data structure in eclipse's debugger, I don't see any reference to whether that attribute is optional or required.
if I were able to find which data structure in xerces holds that critical information, I could provide either a patch or a new class (ValidatingXercesXSMarshaller?) that would be able to validate while marshalling the object (or throw an XB Exception if it were to fail validation.)
Is this reasonable? I think it seems like a good idea to have a marshaller that can validate while marshalling or throw an exception upon failure.
Otherwise, I'd most likely need to force my GenericObjectModelProvider implementation do the validation itself inside the getAttributeValue(etc) method, which would then need to be manually changed if the schema were to change.
Thoughts? -
13. Re: How to force strict validation?
aloubyansky Feb 29, 2008 9:41 AM (in response to rob.stryker)W/o changing APIs you could do something like this:
final String xsd = "<xsd:schema" + " xmlns:jbxb='http://www.jboss.org/xml/ns/jbxb'" + " xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" + " <xsd:element name='root' type='root-type'/>" + " <xsd:complexType name='root-type'>" + " <xsd:annotation>" + " <xsd:appinfo>" + " <jbxb:class impl='" + E.class.getName() + "'/>" + " </xsd:appinfo>" + " </xsd:annotation>" + " <xsd:attribute name='unqualified' type='xsd:string' use='required'/>" + " </xsd:complexType>" + "</xsd:schema>"; String xml = "<root xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='testns'/>"; org.xml.sax.EntityResolver resolver = new org.xml.sax.EntityResolver() { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if(systemId != null && systemId.endsWith("testns")) return new org.xml.sax.InputSource(new StringReader(xsd)); return null; } }; /* Validator.assertValidXml(xml, new org.xml.sax.EntityResolver() { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { if(systemId != null && systemId.endsWith("testns")) return new org.xml.sax.InputSource(new StringReader(xsd)); return null; } }); */ SchemaBinding schema = XsdBinder.bind(new StringReader(xsd), null); Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller(); unmarshaller.setEntityResolver(resolver); unmarshaller.setSchemaValidation(true); Object o = unmarshaller.unmarshal(new StringReader(xml), schema); assertTrue(o instanceof E);
This will throw the exception you expect. The difference is that I had to add noNamespaceSchemaLocation into the xml instead of setting it on the parser.
It might still be useful to expose setProperty() or the parser itself though. -
14. Re: How to force strict validation?
aloubyansky Feb 29, 2008 9:47 AM (in response to rob.stryker)Later XB versions should check the presence of required attributes during marshalling. Xerces-based marshaller is deprecated. org.jboss.xb.binding.sunday.marshalling.MarshallerImpl is the recommended one. It's based on SchemaBinding.