Чтение онлайн

ЖАНРЫ

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

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 <exception>

#include <iostream> // cout

#include <stdexcept> // runtime_error

#include <xercesc/dom/DOM.hpp>

#include <xercesc/parsers/XercesDOMParser.hpp>

#include <xercesc/sax/HandlerBase.hpp>

#include <xercesc/util/PlatformUtils.hpp>

#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) {

cout << "xml error: " << toNative(e.getMessage) << "\n";

return EXIT_FAILURE;

 } catch (const exception& e) {

cout << e.what << "\n";

return EXIT_FAILURE;

 }

}

Обсуждение

Определения DTD обеспечивают простой способ наложения ограничений на документ XML. Например, в DTD можно указать, какие элементы допускаются в документе, какие атрибуты может иметь элемент и может ли конкретный элемент содержать дочерние элементы, текст или и то и другое. Можно также накладывать ограничения на тип, порядок следования и количество дочерних элементов, а также на значения атрибутов.

DTD предназначены для определения подмножества правильно сформированных документов XML, которые характерны для определенной прикладной области. Например, в примере 14.1 важно то, что каждый элемент

animal
имеет дочерние элементы
name
,
species
,
dateOfBirth
,
veterinarian
и
trainer
, а элементы
name
,
species
и
dateOfBirth
содержат только текст в то время, как элементы
veterinarian
и
trainer
имеют атрибуты
name
и
phone
. Более того, элемент
animal
не должен иметь атрибут
phone
, а элемент
veterinarian
не должен иметь дочерний элемент
species
.

DTD в примере 14.11 накладывает ограничения различного типа. Например, приведенное ниже объявление

элемента устанавливает необходимость наличия в элементе животного дочерних элементов
name
,
species
,
dateOfBirth
,
veterinarian
и
trainer
, задаваемых именно в этом порядке.

<!ELEMENT animal (name, species, dateOfBirth,

veterinarian, trainer) >

Аналогично приведенное ниже объявление атрибута указывает на то, что элемент

trainer
должен иметь атрибуты
name
и
phone
, а отсутствие в DTD объявлений других атрибутов для элемента дрессировщика говорит о том, что этот элемент может иметь только два атрибута.

<!ATTLIST trainer

 name CDATA #REQUIRED

 phone CDATA #REQUIRED

>

Документ XML, который содержит DTD и удовлетворяет его требованиям, называют достоверным (valid). XML-парсер, который обнаруживает не только синтаксические ошибки, но и проверяет достоверность документа XML. называется подтверждающим парсером (validating parser). Хотя парсеры

SAX2XMLReader
и
XercesDOMParser
не являются по умолчанию подтверждающими парсерами, в каждом из них предусмотрена функция подтверждения достоверности, которая может подключаться так, как это сделано в примерах 14.13 и 14.14. Аналогично парсер
DOMBuilder
, описанный в рецепте 14 4, может проверять достоверность документа XML, вызывая свой метод
setFeaturе
с аргументами
fgXMLUni::fgDOMValidation
и
true
.

Классы
SAX2XMLReader
,
DOMBuilder
,
DOMWriter
и
XercesDOMParser
поддерживают ряд дополнительных функций. В
SAX2XMLReader
и
DOMBuilder
вы можете включать эти функции, используя методы
setFeature
и
setProperty
. Первый метод принимает строку и булево значение: второй метод принимает строку и
void*
. Запросить включенные функции можно с помощью методов
getFeature
и
getProperty
. Для удобства в Xerces предусмотрены константы с именами фикций и свойств. Класс
DOMWriter
поддерживает
setFeature
, но не поддерживает
setProperty
. Класс
XercesDOMParser
поддерживает оба метода, в нем предусмотрены отдельные методы по установке и получению каждой функции. В документации Xerces вы найдете полный список поддерживаемых дополнительных функций.

Смотри также

Рецепт 14.6.

14.6. Проверка документа XML на соответствие схеме

Проблема

Требуется подтвердить соответствие документа XML схеме, представленной в рекомендациях XML Schema 1.0.

Решение

Используйте библиотеку Xerces совместно с программным интерфейсом SAX2 или с парсером DOM.

Подтверждение соответствия документа XML схеме с использованием программного интерфейса SAX2 осуществляется точно так же, как подтверждение достоверности документа, содержащего DTD, когда схема содержится внутри целевого документа или когда на нее делается ссылка в этом документе. Если требуется проверить документ XML на соответствие внешней схеме, вы должны вызвать метод парсера

setProperty
для включения режима подтверждения внешней схемы. В качестве первого аргумента
setProperty
необходимо использовать
XMLUni::fgXercesSchemaExternalSchemaLocation
или
XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation
в зависимости оттого, используется или нет в схеме целевое пространство имен. Второй аргумент должен определять место расположения схемы, представленное значением типа
const XMLCh*
. Не забудьте привести тип второго аргумента к
void*
, как это сделано в рецепте 14.5.

Поделиться с друзьями: