我正在生成一些XML模式,并希望确保我们的生成器正在创建有效的XML模式文档(不是XML)。我试图想出验证XML Schema文档的代码,但是失败了。我不认为这会是复杂的。针对W3C XML模式定义验证XSD
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当我使用的是URL(URI),以确保XMLSchema.dtd和datatypes.dtd是相对的,我希望他们都可以,但我不确定我怎么能检查。
我猜测它不喜欢XMLSchema.xsd,XMLSchema.dtd和datatypes.dtd捆绑在我的jar中,因此被类加载器加载。无论如何要解决这个问题,以便我可以进入我的下一个障碍,即org.xml.sax.SAXParseException:src-resolve:无法将名称'xml:lang'解析为(n)'属性声明'组件。,假设它的行为与从jar外的目录路径加载XMLSchema时相同。
我的目标是:
- 负载从罐内,使其整齐地码打包XMLSchema.xsd。
- 获取关于xml:lang的下一个错误。
希望我不要问太多!
感谢, 斯图尔特
太棒了,我已经给了它一个去,它运作良好。在决定接受最终答案之前,我想充分评估迈克尔的回应。 – mrswadge 2012-07-30 08:56:22
最后很简单:'XSOMParser parser = new XSOMParser(); parser.setErrorHandler(..); parser.parse(IOUtils.toInputStream(xsdAsString));'虽然我必须确保我使用** xsom14.jar **,因为我在旧的JRE上。我正在使用** relaxngDatatype-2.2.jar **。谢谢您的帮助! – mrswadge 2012-07-30 12:05:11