Мне нужно проверить документы экземпляра схемы XML (XSD), которые сгенерированы программным путем, поэтому я использую следующий фрагмент кода Java, который работает нормально:
SchemaFactory factory = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema xsdSchema = factory.newSchema( // Reads URL every time...
new URL("http://www.w3.org/2001/XMLSchema.xsd"));
Validator xsdValidator = xsdSchema.newValidator();
xsdValidator.validate(new StreamSource(schemaInstanceStream));
Однако при сохранении Файл определения схемы XML локально и ссылается на него следующим образом:
Schema schema = factory.newSchema(
new File("test/xsd/XMLSchema.xsd"));
Сбой со следующим исключением:
org.xml.sax.SAXParseException: schema_reference.4: не удалось прочитать документ схемы 'file: /Users/foo/bar/test/xsd/XMLSchema.xsd', поскольку 1) не удалось найти документ;2) документ не может быть прочитан;3) корневым элементом документа не является.
Я убедился, что файл существует и доступен для чтения, выполнив exists()
и canRead()
утверждения для объекта File
.Я также скачал файл с несколькими различными утилитами (веб-браузер, wget), чтобы убедиться в отсутствии повреждений.
Любая идея, почему я могу проверять документы экземпляра XSD при генерации схемы из HTTP-URLно я получаю вышеупомянутое исключение при попытке создать из локального файла с тем же содержимым?
[Редактировать]
Чтобы уточнить, я попробовал несколько формfactory.newSchema(...)
с использованием Readers и InputStreams (вместо непосредственного доступа к файлу) и все равно получит точно такую же ошибку.Более того, я выгрузил содержимое файла перед его использованием или различные входные потоки, чтобы убедиться, что он правильный.Довольно досадно.
Полный ответ
Оказывается, есть три дополнительных файла, на которые ссылается схема XML, которые также должны храниться локально, а XMLSchema.xsd
содержит оператор импорта, чей атрибут schemaLocation
долженбыть изменен.Вот файлы, которые должны быть сохранены в том же каталоге:
- XMLSchema.xsd - измените
schemaLocation
на "xml.xsd
" в элементе "import" для XMLПространство имен. - XMLSchema.dtd - как есть.
- datatypes.dtd - как есть.
- xml.xsd - как есть.
Спасибо @Blaise Doughan и @Tomasz Nurkiewicz за подсказки.