I am generating some XML Schemas and would like to ensure that our generator is creating valid XML Schema documents (Not XML). I was trying to come up with the code to validate the XML Schema document, but failing miserably. I didn't think it would be this complex.
private void validateXsd( String xsdAsString ) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setFeature( "http://apache.org/xml/features/validation/schema", true );
SchemaFactory schemaFactory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
URL xmlSchemaXSD = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/XMLSchema.xsd" );
URL xmlSchemaDTD = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/XMLSchema.dtd" );
URL xmlSchemaDataTypes = this.getClass().getClassLoader().getResource( "com/metamodel/xsd/datatypes.dtd" );
// requires that XMLSchema.dtd and datatypes.dtd are present in the same directory with the XMLSchema.xsd.
factory.setSchema( schemaFactory.newSchema( xmlSchemaXSD ) );
SAXParser parser = factory.newSAXParser();
// parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema" );
XMLReader reader = parser.getXMLReader();
reader.setErrorHandler( new SimpleErrorHandler() );
reader.parse( new InputSource( IOUtils.toInputStream( xsdAsString ) ) );
} catch( SAXParseException e ) {
e.printStackTrace( System.err );
} catch ( ParserConfigurationException e ) {
e.printStackTrace( System.err );
} catch ( SAXException e ) {
e.printStackTrace( System.err );
} catch ( IOException e ) {
e.printStackTrace( System.err );
}
}
This code is fairly close to what I need to do, but I'm getting the following errors.
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'jar:file:/r:/as4ot/lib/metamodel.jar!/com/metamodel/xsd/XMLSchema.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:236)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:172)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:382)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:316)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaError(XSDHandler.java:2245)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchema(XSDHandler.java:1590)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:438)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:556)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:523)
at com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl.newSchema(SchemaFactoryImpl.java:206)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:489)
at javax.xml.validation.SchemaFactory.newSchema(SchemaFactory.java:521)
I'm using a URL when calling setSchema( uri ) to ensure that XMLSchema.dtd and datatypes.dtd are relative and I hope they are available, but I am unsure how I can check this.
I'm guessing that it doesn't like the fact the XMLSchema.xsd, XMLSchema.dtd and datatypes.dtd are bundled in my jar and hence loaded by the classloader. Is there anyway to solve this so that I can move onto my next hurdle which is org.xml.sax.SAXParseException: src-resolve: Cannot resolve the name 'xml:lang' to a(n) 'attribute declaration' component. assuming that it behaves the same as when I loaded the XMLSchema from a directory path outside of a jar.
My goals are:
Hopefully I'm not asking too much!
Thanks, Stuart
I wouldn't validate an XSD using the approach you described for a couple of reasons, the most important one being that the XSD as a language is weak so in itself it does not capture the full spec. So, most likely, you may validate something that in fact is not valid.
For XSD validation you have specialized processors; Java has XSOM; follow the user guide.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With