JAXP - debug XSD catalog look up

℡╲_俬逩灬. 提交于 2019-12-13 02:25:30

问题


I have a situation where we want to validate an XML document held as a byte stream in memory, against an XSD placed amongst others in a file system. We would like to avoid having the file name explicitly mentioned in the XML file but instead tell the XML parser to use a catalog of one or more XSD files for validation.

My attempt to create a DocumentBuilder provider (for Guice 3.0) looks like:

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

(and I have also tried with file names too). Eclipse accepts the XSD - when put in the catalog it can validate the XML dealt with here

It appears to the naked eye that the parser halts briefly when trying to validate. This might be a network lookup.

-Djaxp.debug=1 only adds these lines

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

How can I get the parser in JDK 6 to tell me what it is doing? If I cannot do that, how do I inspect the XML Catalog usage inside it to see why the XSDs provided are not selected?

What obvious thing have I overlooked?


回答1:


You say

We would like to avoid having the file name explicitly mentioned in the XML file

How then would the parser be able to select the appropriate schema?

What you can try, is to create a Schema, using a SchemaFactory, based on all the available schema resources and attach that to the document builder factory. The parser will then automatically validate the document against this "super schema".

If your set of schemas has internal dependencies (i.e. import or include), make sure that those references are resolved correctly using relative URLs or a specialised resolver.

UPDATE:

After reading this, http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPDOM8.html, a bit more carefully, I realize that you approach should have the same effect as my proposal, so something else is going n. I can only say that what I describe works very well.



来源:https://stackoverflow.com/questions/7632422/jaxp-debug-xsd-catalog-look-up

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!