I have a situation where we want to check an XML document stored in a stream of bytes in memory against an XSD placed among others on the file system. We would like the file name explicitly mentioned in the XML file, but instead ask the XML parser to use the directory for one or more XSD files for verification.
My attempt to create a DocumentBuilder provider (for Guice 3.0) looks like this:
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 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 also tried with file names too). Eclipse accepts XSD - when pasted into a directory, it can validate the XML discussed here.
It seems to the naked eye that the parser stops for a while when trying to check. It can be a network search.
-Djaxp.debug=1 adds only 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 does? If I cannot do this, how can I test the use of the XML catalog inside it to find out why the XSD were not selected?
What obvious have I missed?
java xml validation jaxp
Thorbjørn Ravn Andersen
source share