简体   繁体   中英

Validating XSD against W3C XML Schema Definition

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:

  • Load the XMLSchema.xsd from inside the jar so that it is neatly packaged with the code.
  • Get past the next error regarding xml:lang.

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 .

I agree with Petru that validating a schema against the schema for schema documents is not a very useful thing to do, because it won't detect all errors in your schema. The only real way to ensure that your schema is valid is to pass it to a schema processor.

For example, with Saxon

Processor p = new Processor(true);
StreamSource ss = new StreamSource(new File('mySchema.xsd');
p.getSchemaManager().load(ss);

will tell you whether your schema is valid or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM