14.5. Проверка документа XML на соответствие определению DTD
Проблема
Требуется проверить документ XML на соответствие DTD.
Решение
Используйте библиотеку Xerces с парсером SAX2 (простой программный XML-интерфейс) или с парсером DOM.
Для проверки документа XML при использовании SAX2 получите SAX2XMLReader
, как показано в примере 14.8. Затем включите режим проверки DTD, вызывая метод парсера setFeature()
с аргументами xercesc::XMLUni::fgSAX2CoreValidation
и true
. Наконец, зарегистрируйте обработчик ErrorHandler
для получения уведомлений о нарушении DTD и вызовите метод парсера parse()
, указывая в качестве его аргумента имя вашего документа XML.
Для проверки документа XML при использовании парсера DOM сначала сконструируйте экземпляр XercesDOMParser
. Затем включите режим проверки DTD, вызывая метод парсера setValidationScheme()
с аргументом xercesc::XercesDOMParser::Val_Always
. Наконец, зарегистрируйте обработчик ErrorHandler
для получения уведомлений о нарушении DTD и вызовите метод парсера parse()
, указывая в качестве его аргумента имя вашего документа XML.
Здесь я использую класс XercesDOMParser
, т.е. XML-парсер, который входил в состав Xerces еще до того, как был разработан интерфейс DOMBuilder
— парсера DOM уровня 3. Применение XercesDOMParser
позволяет немного упростить пример, но при желании вы можете вместо него использовать DOMBuilder
. См. обсуждение этого рецепта и рецепт 14.4.
Для примера предположим, что вы модифицируете документ XML animals.xml из примера 14.1 для того, чтобы он содержал ссылку на внешнее определение DTD, как показано в примерах 14.11 и 14.12. Программный код, выполняющий проверку документа с использованием программного интерфейса SAX2, приводится в примере 14.13; программный код, выполняющий проверку этого документа с использованием парсера DOM, приводится в примере 14.14.
Пример 14.11. DTD animals.dtd для файла animals.xml
veterinarian, trainer) >
name CDATA #REQUIRED
phone CDATA #REQUIRED
>
name CDATA #REQUIRED
phone CDATA #REQUIRED
>
Пример 14.12. Модифицированный файл animals.xml, содержащий DTD
Пример 14.13. Проверка документа animals.xml на соответствие DTD с использованием программного интерфейса SAX2
/*
* Операторы #include из примера 14.8, кроме включения вектора который
здесь не нужен
*/
#include // runtime_error
#include
using namespace std;
using namespace xercesc;
/*
* Определить XercesInitializer, как это сделано в примере 14.8, и
* CircusErrorHandler, как это сделано в примере 14.7
*/
int main() {
try {
// Инициализировать Xerces и получить парсер
SAX2 XercesInitializer init;
auto_ptr
parser(XMLReaderFactory::createXMLReader());
// Включить режим проверки
parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
// Зарегистрировать обработчик ошибок для получения уведомлений о
// нарушениях DTD
CircusErrorHandler error;
parser->setErrorHandler(&error);
parser->parse("animals.xml");
} catch (const SAXException& e) {
cout << "xml error " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const XMLException& e) {
cout << "xml error " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const exception& e) {
cout << e.what() << "\n";
return EXIT_FAILURE;
}
}
Пример 14.14. Проверка документа animals.xml на соответствие DTD animals.dtd с использованием парсера XercesDOMParser
#include
#include // cout
#include // runtime_error
#include
#include
#include
#include
#include "xerces_strings.hpp" // Пример 14.4
using namespace std;
using namespace xercesc;
/*
* Определить XercesInitializer, как это сделано в примере 14.8
* и CircusErrorHandler, как это сделано в примере 14.7
*/
int main() {
try {
// Инициализировать Xerces и сконструировать DOM-парсер.
XercesInitializer init;
XercesDOMParser parser;
// Включить режим проверки DTD
parser.setValidationScheme(XercesDOMParser::Val_Always);
// Зарегистрировать обработчик ошибок для получения уведомлений о
// нарушениях схемы
CircusErrorHandler handler;
parser.setErrorHandler(&handler);
// Выполнить синтаксический анализ вместе с проверкой.
parser.parse("animals.xml");
} catch (const SAXException& e) {
cout << "xml error: " << toNative(e.getMessage()) << "\n";
return EXIT_FAILURE;
} catch (const XMLException& e) {
Читать дальше