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

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

Жанры

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)

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

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

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

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

Мужчина моей судьбы

Ардова Алиса
2. Мужчина не моей мечты
Любовные романы:
любовно-фантастические романы
8.03
рейтинг книги
Мужчина моей судьбы

Прорвемся, опера! Книга 3

Киров Никита
3. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 3

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

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

Измена. Право на сына

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

Игра на чужом поле

Иванов Дмитрий
14. Девяностые
Фантастика:
попаданцы
альтернативная история
5.50
рейтинг книги
Игра на чужом поле

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Ворон. Осколки нас

Грин Эмилия
2. Ворон
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ворон. Осколки нас

Сумеречный стрелок

Карелин Сергей Витальевич
1. Сумеречный стрелок
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок

Измена. Испорченная свадьба

Данич Дина
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Измена. Испорченная свадьба

Прометей: Неандерталец

Рави Ивар
4. Прометей
Фантастика:
героическая фантастика
альтернативная история
7.88
рейтинг книги
Прометей: Неандерталец

Генерал-адмирал. Тетралогия

Злотников Роман Валерьевич
Генерал-адмирал
Фантастика:
альтернативная история
8.71
рейтинг книги
Генерал-адмирал. Тетралогия

Четвертый год

Каменистый Артем
3. Пограничная река
Фантастика:
фэнтези
9.22
рейтинг книги
Четвертый год