针对多个任意模式validationXML

考虑一个XML文档,它像下面的多个模式一样开始(这不是一个特定于Spring的问题;这只是一个方便的XML文档):

 

我想validation文档,但我不知道文档作者将使用哪些名称空间。 我相信文档作者,所以我愿意下载任意模式URL。 我如何实现我的validation器?

我知道我可以使用DocumentBuilderFactory实例指定我的模式我调用setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", new String[] {...})但我不知道知道架构URL,直到解析文档。

当然,我可以在解析文档之后自己提取XSD URL,然后通过validation器运行它,如上所述指定"http://java.sun.com/xml/jaxp/properties/schemaSource" ,但肯定已经有了自动执行此操作的实现?

我还没有确认这一点,但您可能会发现使用JAXP Validation API来创建validation器并validation来自DOM的输入,该DOM包含内联架构和多个validation根 。

尤其是,

 factory.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking); factory.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, honourAllSchemaLocations); 

请原谅我回答自己的问题…来自@Eugene Yokota和@ forty-two的其他答案非常有帮助,但我认为他们不够完整,不能接受。 我需要做更多的工作,将建议写入下面的最终解决方案。 以下在JDK 1.6下完美运行。 它没有足够的错误检查(请参阅Eugene的答案中的链接,这是一个非常完整的解决方案 – 但不可重复使用),我相信它也不会缓存下载的XSD。 我认为它利用了Xerces解析器的特定function,因为apache.orgfunctionURL。

  InputStream xmlStream = ... DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); factory.setValidating(true); factory.setXIncludeAware(true); factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); factory.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true); factory.setFeature("http://apache.org/xml/features/honour-all-schemaLocations", true); factory.setFeature("http://apache.org/xml/features/validate-annotations", true); factory.setFeature("http://apache.org/xml/features/generate-synthetic-annotations", true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new ErrorHandler() { public void warning(SAXParseException exception) throws SAXException { LOG.log(Level.WARNING, "parse warn: " + exception, exception); } public void error(SAXParseException exception) throws SAXException { LOG.log(Level.SEVERE, "parse error: " + exception, exception); } public void fatalError(SAXParseException exception) throws SAXException { LOG.log(Level.SEVERE, "parse fatal: " + exception, exception); } }); Document doc = builder.parse(xmlStream); 

如果你像这样创建一个DocumentBuilderFactory:

  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(true); dbf.setNamespaceAware(true); dbf.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); 

然后,您可以在此工厂创建的DocumentBuilder实例上设置EntityResolver ,以便有机会解析指令中引用的架构位置。 指定的位置将出现在systemId参数中。

我认为构建器会自动执行此操作,而不指定解析器,但显然不是开箱即用的。 可能是由另一个function,属性或属性控制?