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

на главную - закладки

Жанры

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

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

Шрифт:

Несколько важных особенностей SAX2 не проиллюстрировано в примерах 14.6, 14.7 и 14.8. Например, класс

SAX2XMLReader
содержит перегрузку метода
parse
, которая принимает в качестве аргумента экземпляр
xercesc::InputSource
вместо строки в С-стиле.
InputSource
является абстрактным классом, инкапсулирующим источник символьных данных; конкретные его подклассы, в том числе
xercesc::MemBufInputSource
и
xercesc::URLInputSource
, позволяют парсеру SAX2 анализировать документ XML, который находится не в локальной файловой системе.

Более

того, интерфейс
ContentHandler
содержит много дополнительных методов, например
startDocument
и
endDocument
, которые сигнализируют о начале и конце документа XML, и
setLocator
, который позволяет задать объект
Locator
, отслеживающий текущую позицию анализируемого файла. Существуют также другие интерфейсы обработчиков, включая
DTDHandler
и
EntityResolver
(соответствующие базовой спецификации SAX 2.0), а также
DeclarationHandler
и
LexicalHandler
(соответствующие стандартизованным расширениям SAX 2.0).

Кроме того, можно в одном классе реализовать несколько интерфейсов обработчиков. Это можно легко сделать в классе

xercesc::DefaultHandler
, потому что он является производным от всех интерфейсов обработчиков и содержит реализации своих виртуальных функций, в которых не выполняется никаких действий. Следовательно, я мог бы добавить методы из
CircusErrorHandler
в
CircusContentHandler
и следующим образом модифицировать пример 14.8.

// Зарегистрировать обработчики

CircusContentHandler handler(animalList);

parser->setContentHandler(&handler);

parser->setErrorHandler(&handler);

Пример 14.8 имеет еще одну, последнюю особенность, которую вы должны были заметить: обработчик

CircusContentHandler
не проверяет корректность структуры экземпляра анализируемого документа, т.е. не убеждается в том, что корневым является элемент
animalList
или что все дочерние элементы корня являются элементами
animal
. Это сильно отличается от примера 14.3. Например, функция
main
из примера 14.3 проверяет то, что элементом верхнего уровня является
animalList
, а функция
nodeToAnimal
проверяет то, что ее аргументы представляют элемент
animal
, содержащий точно пять дочерних элементов типа
name
,
species
,
dateOfBirth
,
veterinarian
и
trainer
.

Пример 14.6 можно модифицировать, чтобы он выполнял подобного рода проверки. Например, обработчик

ContentHandler
в примере 14.9 удостоверяется в том, что корневым элементом документа является
animalList
и что его дочерние элементы имеют тип
animal
, а дочерние элементы элемента
animal
не содержат других элементов. Это можно сделать с помощью трех флагов типа
boolean
,
parsingAnimalList_
,
parsingAnimal_
и
parsingAnimalChild_
, которые регистрируют анализируемую в данный момент область документа. Методы
startElement
и
endElement
просто обновляют эти флаги и проверяют их согласованность, делегируя задачу обновления текущего объекта Animal вспомогательным методам
startAnimalChild
и
endElementChild
, реализация которых очень напоминает реализацию методов
startElement
и
endElement
из примера 14.6.

Пример 14.9. Обработчик SAX2 ContentHandler документа animals.xml, который проверяет структуру документа

// Реализует функции обратного вызова, которые получают символьные данные и

// уведомляют о начале и конце элементов

class CircusContentHandler : public DefaultHandler {

public:

 CircusContentHandler(vector<Animal>& animalList)

: animalList_(animalList), // заполняемый список

parsingAnimalList_(false), // состояние анализа

parsingAnimal_(false), // состояние анализа

parsingAnimalChild_(false) // состояние анализа

{}

 // Получает уведомления от парсера при каждой встрече начала

 // какого-нибудь элемента

 void startElement(

const XMLCh *const uri, // uri пространства имен

const XMLCh *const localname, // простое имя тега

const XMLCh *const qname, // квалифицированное имя тега

const Attributes &attrs) // Набор атрибутов

 {

static XercesString animalList = fromNative("animalList");

static XercesString animal = fromNative("animal");

static XercesString xmlns =

fromNative("http://www.feldman-family-circus.com");

// Проверяет uri пространства имен

if (uri != xmlns)

throw runtime_error(

string("wrong namespace uri: ") + toNative(uri)

);

// (i) Обновить флаги parsingAnimalList_, parsingAnimal_

// и parsingAnimalChild_, которые показывают, в какой части

// документа мы находимся

// (ii) Убедиться, что элементы имеют правильную вложенность

//

// (iii) Делегировать основную работу методу

// startAnimalChild

if (!parsingAnimalList_) {

// Мы только что встретили корень документа

if (localname == animalList) {

parsingAnimalList_ = true; // Обновить состояние анализа.

} else {

// Неправильная вложенность

throw runtime_error(

string("expected 'animalList', got ") + toNative(localname)

Поделиться:
Популярные книги

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

Ковальчук Олег Валентинович
4. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 4

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4