Xerces XMLSchemaFactory: не удается найти объявление элемента - PullRequest
2 голосов
/ 19 февраля 2011

Я хочу проверить файл 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 Ответ

2 голосов
/ 20 февраля 2011

Я бы рискнул предположить, что на самом деле у вас нет Xerces на пути к классам в случае сбоя.

-Djaxp.debug точно скажет, какая реализация активна, когда вы вызываетеJAXP APIS, который вы вызываете.

Если это так, и это не просто результат ошибки в вашем пути к классам, вы действительно можете специально «создавать» новые классы Xerces вместо вызова универсальной фабрики JAXPметоды.Я сделал это.

edit

комментарии указывают, что это веб-приложение.Классы JAXP - это одна из тех вещей, которые больно вставлять в веб-приложение, учитывая правила загрузки классов.Вы должны хотя бы попытаться поместить его в системный путь tomcat и посмотреть, что произойдет.

...