首页 文章

根据W3C XML模式定义验证XSD

提问于
浏览
3

我正在生成一些XML Schema,并希望确保我们的生成器正在创建有效的XML Schema文档(非XML) . 我试图提出验证XML Schema文档的代码,但是失败了 . 我不认为这会很复杂 .

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 );
    }
  }

这段代码非常接近我需要做的,但是我遇到了以下错误 .

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)

我在调用setSchema(uri)时使用URL来确保XMLSchema.dtd和datatypes.dtd是相对的,我希望它们可用,但我不确定如何检查它 .

我认为XMLSchema.xsd,XMLSchema.dtd和datatypes.dtd捆绑在我的jar中,因此由类加载器加载 . 无论如何要解决这个问题,以便我可以进入我的下一个障碍,即org.xml.sax.SAXParseException:src-resolve:无法将名称'xml:lang'解析为(n)'attribute declaration'组件 . 假设它的行为与从jar外部的目录路径加载XMLSchema时的行为相同 .

我的目标是:

  • 从jar中加载XMLSchema.xsd,使其与代码整齐地打包在一起 .

  • 获取有关xml:lang的下一个错误 .

希望我不要求太多!

谢谢,斯图尔特

2 回答

  • 2

    我不会使用您描述的方法验证XSD有几个原因,最重要的一个原因是XSD作为一种语言很弱,所以它本身并不能捕获完整的规范 . 因此,最有可能的是,您可能会验证实际上无效的内容 .

    对于XSD验证,您有专门的处理器; Java有XSOM;按照user guide .

  • 3

    我同意Petru认为,针对模式文档的模式验证模式不是一件非常有用的事情,因为它不会检测模式中的所有错误 . 确保架构有效的唯一真正方法是将其传递给架构处理器 .

    例如,撒克逊人

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

    将告诉您您的架构是否有效 .

相关问题