Xerces XMLSchemaFactory: не удается найти объявление элемента
Я хочу проверить файл XML (который не имеет ни пространства имен, ни описания схемы в файле XML) по файлу XSD.
XML-файл выглядит так:
<?xml version="1.0" encoding="UTF-8"?>
<report> ... </report>
И файл XSD, это:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="report">
...
</xs:element>
</xs:schema>
Код похож на следующее:
SchemaFactory xsdFac = SchemaFactory.newInstance(
XMLConstants.W3C_XML_SCHEMA_NS_URI);
xsdFac.setErrorHandler( ... );
Schema xsd = xsdFac.newSchema(xsdUrl); // xsdUrl works
Validator xsdValidator = xsd.newValidator();
xsdValidator.validate(new DOMSource(doc)); // doc is correct
Я потратил на это 3 часа, так как он работает локально на моем ПК, раньше он работал на сервере (я думаю), но теперь он не работает на сервере. Я попытался определить различия между моим ПК и сервером, но они оба используют одни и те же файлы JAR и так далее.
Во всяком случае, я определил следующую разницу. Я не передавал имя класса SchemaFactory.newInstance
метод (почти наверняка ошибка), когда я распечатал имя класса xsdFac
Я видел, что это было по-разному между локально и на сервере. Я не думаю, что хочу понять, почему это произошло (я понятия не имею), я думаю, что лучше найти тот, который работает, и явно указать его.
- На моем ПК (работает) было
com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory
, Если я явно укажу, что наnewInstance
позвоните, затем он работает на ПК и на сервере. - На сервере (не работал) это было
org.apache.xerces.jaxp.validation.XMLSchemaFactory
, Если я явно установить это наnewInstance
звоните, тогда я получаю одинаковую ошибку как на ПК, так и на сервере.
Обратите внимание на com.sun
в начале того, который работает.
По крайней мере, у меня есть решение, это хорошо. Но я думаю, что я не должен использовать com.sun
классы явно в моем коде?
Дополнительная информация:
- Я получаю ошибку:
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'report'
- Это та же ошибка, которую я получаю, когда в рабочей версии я изменяю имя элемента на что-то другое, то, чего нет в схеме. Поэтому я думаю, что это просто означает: "Я понимаю вашу схему и понимаю XML, и вы использовали элемент, который не объявлен нигде в схеме".
xercesImpl-2.9.1.jar
есть в моем проекте (как на сервере, так и на ПК).- Этот JAR содержит
XMLSchemaFactory.class
в пакете, указанном в нерабочей версии (то есть заставил бы меня поверить, что он есть, доступен для поиска и должен работать, и в конце концов я не получаю никаких исключений, касающихся классов, не найденных) doc
объект, который я анализирую, в обоих случаяхorg.apache.xerces.dom.DeferredDocumentImpl
Итак, мой вопрос: я хотел бы использовать явную реализацию Xerces фабрики схем (я думаю), так как я включаю JAR, и у меня есть объект Document из Xerces, и в основном я все равно использую валидатор Xerces (в рабочий случай com.sun
).
У кого-нибудь есть подобный опыт?
1 ответ
Я бы рискнул предположить, что на самом деле у вас нет Xerces на пути к классам в случае неудачи.
-Djaxp.debug точно скажет вам, какая реализация активна, когда вы вызываете вызываемую JAXP APIS.
Если это так, и это не просто результат ошибки в вашем пути к классам, вы действительно можете специально "создавать новые" классы Xerces вместо вызова общих фабричных методов JAXP. Я сделал это.
редактировать
комментарии указывают, что это веб-приложение. Классы JAXP - это одна из тех вещей, которые больно помещать в веб-приложение, учитывая правила загрузки классов. Вы должны хотя бы попытаться поместить его в системный путь класса tomcat и посмотреть, что произойдет.