JAXP - поиск в каталоге отладки XSD
У меня есть ситуация, когда мы хотим проверить XML-документ, который хранится в виде байтового потока в памяти, в сравнении с XSD, размещенным среди других в файловой системе. Мы хотели бы избежать явного упоминания имени файла в файле XML, а вместо этого сказать парсеру XML использовать каталог одного или нескольких файлов XSD для проверки.
Моя попытка создать провайдера DocumentBuilder (для Guice 3.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 не выбраны?
Какую очевидную вещь я упустил из виду?
1 ответ
Ты говоришь
Мы хотели бы избежать явного упоминания имени файла в файле XML
Как тогда парсер сможет выбрать подходящую схему?
Что вы можете попробовать, это создать Schema
, используя SchemaFactory
на основе всех доступных ресурсов схемы и присоедините их к фабрике компоновщика документов. Затем анализатор автоматически проверит документ на соответствие этой "супер-схеме".
Если ваш набор схем имеет внутренние зависимости (т.е. импортирует или включает), убедитесь, что эти ссылки разрешены правильно с использованием относительных URL-адресов или специального преобразователя.
ОБНОВИТЬ:
Прочитав это, http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JAXPDOM8.html, немного более тщательно, я понимаю, что ваш подход должен иметь тот же эффект, что и мое предложение, так что-то еще собирается п. Я могу только сказать, что то, что я описываю, работает очень хорошо.