在我的情况下,我们希望根据文件系统中放置的XSD来验证作为字节流保存在内存中的XML文档。我们希望避免在XML文件中显式地提到文件名,而是告诉XML解析器使用一个或多个XSD文件的目录进行验证。
我创建DocumentBuilder提供程序(用于Guice3.0)的尝试如下所示:
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);
}
}
}(我也尝试过使用文件名)。Eclipse接受XSD --当放在目录中时,它可以验证这里处理的XML。
在肉眼看来,解析器在尝试验证时会短暂停止。这可能是一个网络查找。
-Djaxp.debug=1只添加这些行
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如何让JDK 6中的解析器告诉我它在做什么?如果我不能这样做,我如何检查XML目录的使用情况,以了解为什么没有选择所提供的XSD?
我忽略了什么明显的事情?
发布于 2011-10-03 10:33:17
你说
我们希望避免在XML文件中显式提到文件名
那么解析器如何能够选择合适的模式呢?
您可以尝试的是,基于所有可用的架构资源,使用Schema创建一个SchemaFactory,并将其附加到文档构建器工厂。然后,解析器将根据这个“超级模式”自动验证文档。
如果您的模式集具有内部依赖关系(即导入或包含),请确保使用相对URL或专用解析器正确解析这些引用。
更新:
在读了这篇文章之后,http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPDOM8.html,再仔细一点,我意识到你的方法应该和我的建议有同样的效果,所以还有别的事情要做,我只能说我所描述的效果很好。
https://stackoverflow.com/questions/7632422
复制相似问题