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 и посмотреть, что произойдет.

Другие вопросы по тегам