Java JAXP-调试XSD目录查找

Java JAXP-调试XSD目录查找,java,xml,validation,jaxp,Java,Xml,Validation,Jaxp,我遇到了这样一种情况,即我们希望验证内存中作为字节流保存的XML文档,与文件系统中放置的XSD进行对比。我们希望避免在XML文件中明确提到文件名,而是告诉XML解析器使用一个或多个XSD文件的目录进行验证 我尝试为Guice 3.0创建DocumentBuilder提供程序,如下所示: public class ValidatingDocumentBuilderProvider implements Provider<DocumentBuilder> { s

我遇到了这样一种情况,即我们希望验证内存中作为字节流保存的XML文档,与文件系统中放置的XSD进行对比。我们希望避免在XML文件中明确提到文件名,而是告诉XML解析器使用一个或多个XSD文件的目录进行验证

我尝试为Guice 3.0创建DocumentBuilder提供程序,如下所示:

public class ValidatingDocumentBuilderProvider implements
        Provider<DocumentBuilder> {

    static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
    static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
    static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";

    Logger log = getLogger(ValidatingDocumentBuilderProvider.class);

    DocumentBuilderFactory dbf;

    public synchronized DocumentBuilder get() { // dbf not thread-safe

        if (dbf == null) {
            log.debug("Setting up DocumentBuilderFactory");

            // http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPDOM8.html
            dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            dbf.setValidating(true);
            dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
            // parser should look for schema reference in xml file

            // Find XSD's in current directory.

            FilenameFilter fileNameFilter = new FilenameFilter() {

                public boolean accept(File dir, String name) {
                    return name.toLowerCase().endsWith(".xsd");
                }
            };
            File[] schemaFiles = new File(".").listFiles(fileNameFilter);

            dbf.setAttribute(JAXP_SCHEMA_SOURCE, schemaFiles);

            log.debug("{} schema files found", schemaFiles.length);
            for (File file : schemaFiles) {
                log.debug("schema file: {}", file.getAbsolutePath());
            }

        }

        try {
            return dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new RuntimeException("get DocumentBuilder", e);
        }
    }
}
如何让JDK 6中的解析器告诉我它在做什么?如果我不能做到这一点,我如何检查其中的XML目录使用情况,以了解为什么没有选择提供的XSD

我忽略了什么明显的事情?

你说

我们希望避免在XML文件中明确提到文件名

那么解析器将如何选择合适的模式呢

您可以尝试的是基于所有可用的模式资源,使用SchemaFactory创建一个模式,并将其附加到DocumentBuilder工厂。然后,解析器将根据这个超级模式自动验证文档

如果您的模式集具有内部依赖关系,即导入或包含,请确保使用相对URL或专用解析程序正确解析这些引用

更新:


仔细阅读后,我意识到你的方法应该和我的建议有同样的效果,所以其他的事情正在发生。我只能说,我所描述的非常有效。

据我所知,每个XSD都提到它可以验证哪个名称空间。如果XML中使用了这些名称空间中的任何一个,我希望解析器使用相应的XSD。
JAXP: find factoryId =javax.xml.parsers.DocumentBuilderFactory
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl using ClassLoader: null