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

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

Жанры

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

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

Шрифт:

// Преобразует строку со стандартными символами

// в строку с расширенным набором символов

inline XercesString fromNative(const char* str) {

boost::scoped_array<XMLCh> ptr(xercesc::XMLString::transcode(str));

 return XercesString(ptr.get);

}

// Преобразует строку со стандартными символами

// в строку с расширенным набором символов.

inline XercesString fromNative(const std::string& str) {

 return fromNative(str.c_str);

}

//
Преобразует строку с расширенным набором символов

// в строку со стандартными символами.

inline std::string toNative(const XMLCh* str) {

boost::scoped_array<char> ptr(xercesc::XMLString::transcode(str));

 return std::string(ptr.get);

}

// Преобразует строку с расширенным набором символов в строку со стандартными символами.

inline std::string toNative(const XercesString& str) {

 return toNative(str.c_str);

}

#endif // #ifndef XERCES_STRINGS_HPP_INCLUDED

Для выполнения преобразований между строками Xerces и

std::wstring
просто используйте конструктор
std::basic_string
, передавая ему два итератора. Например, можно определить следующие две функции.

// Преобразует строку Xerces в строку std::wstring

std::wstring xercesToWstring(const XercesString& str) {

 return std::wstring(str.begin, str.end);

}

// Преобразует строку std::wstring в строку XercesString

XercesString wstringToXerces(const std::wstring& str) {

 return XercesString(str.begin, str.end);

}

В этих функциях используется тот факт, что

wchar_t
и
XMLCh
являются интегральными типами, каждый из которых может неявно преобразовываться в другой; это должно работать независимо от размера
wchar_t
, пока не используются значения, выходящие за диапазон
XMLCh
. Вы можете определить подобные функции, принимающие в качестве аргументов строки в C-стиле, используя конструктор
std::basic::string
, которому передаются в качестве аргументов массив символов и длина.

Обсуждение

Для представления строк в коде Unicode библиотека Xerces использует последовательности символов

XMLCh
, завершаемые нулем. Тип
XMLCh
вводится с помощью
typedef
как интегральный тип, зависящий от реализации и содержащий не менее 16 бит, которых достаточно для представления символов почти любого языка. Xerces применяет символьную кодировку UTF-16, что подразумевает теоретическую возможность представления некоторых символов в коде Unicode в виде последовательности из нескольких символов
XMLCh
; однако практически можно считать, что каждый символ
XMLCh
непосредственно представляет один символ в коде Unicode, т.е. имеет числовое значение символа Unicode.

Одно время тип

XMLCh
определялся с помощью
typedef
как
wchar_t
, что позволяло легко сохранять копию строки Xerces как
std::wstring
. Однако в настоящее время Xerces определяет
XMLCh
на всех платформах с помощью
typedef
как
unsigned short
. Кроме всего прочего
это означает, что на некоторых платформах типы
XMLCh
и
wchar_t
имеют разный размер. Поскольку Xerces может изменить в будущем определение
XMLCh
, нельзя рассчитывать на то, что
XMLCh
будет идентичен какому-то конкретному типу. Поэтому, если требуется сохранить копию строки Xerces, следует использовать тип
std::basic_string<XMLCh>
.

При использовании Xerces вам придется часто выполнять преобразования между строками со стандартными символами и строками Xerces; для этой цели в Xerces предусмотрена перегруженная функция

transcode
.
transcode
может преобразовать строку Unicode в строку со стандартными символами, использующую «родную» кодировку символов, или строку с «родной» кодировкой со стандартными символами в строку Unicode. Однако смысл родной кодировки точно не определен, поэтому если вы программируете в среде, в которой часто используется несколько кодировок символов, то вам придется все взять в свои руки и выполнять преобразования особым образом, используя либо фасет
std::codecvt
, либо подключаемые службы перекодировки (pluggable transcoding services) библиотеки Xerces, описанные в документации Xerces. Однако во многих случаях вполне достаточно использовать
transcode
.

Память под возвращаемые функцией

transcode
строки, завершающиеся нулем, динамически выделяется при помощи оператора
new
в форме массива; вам придется строку удалять самому, используя оператор
delete[]
. Это создает небольшую проблему управления памяти, поскольку обычно требуется копировать строку или записывать ее в поток до ее удаления, а эти операции могут выбросить исключение. Я решаю эту проблему в примере 14.4 с помощью шаблона
boost::scoped_array
, который динамически выделяет память под массив и автоматически удаляет его при выходе из области видимости, даже если выбрасывается исключение. Например, рассмотрим реализацию функции
fromNative
.

inline XercesString fromNative(const char* str) {

 boost::scoped_array<XMLCh> ptr(xercesc::XMLString::transcode(str));

 return XercesString(ptr.get);

}

Здесь

ptr
становится обладателем возвращенной функцией
transcode
строки с нулевым завершающим символом и освобождает ее, даже если конструктор
XercesString
выбрасывает исключение
std::bad_alloc
.

14.3. Синтаксический анализ сложного документа XML

Проблема

Имеется некоторый набор данных, хранимых в документе XML, внутри которого используется DTD или применяются пространства имен XML. Требуется выполнить синтаксический анализ документа и превратить содержащиеся в нем данные в набор объектов C++.

Решение

Используйте реализацию Xerces в виде программного интерфейса SAX2 (простой программный интерфейс для XML, версия 2.0). Во-первых, создайте класс, производный от

xercesc::ContentHandler
; этот класс будет получать уведомления с информацией о структуре и содержимом вашего документа XML по мере его анализа. Затем при желании можно создать класс, производный от
xercesc::ErrorHandler
, для получения предупреждений и сообщений об ошибках. Сконструируйте парсер типа
xercesc::SAX2XMLReader
, зарегистрируйте экземпляры классов вашего обработчика, используя методы парсера
setContentHandler
и
setErrorHandler
. Наконец, вызовите метод парсера
parse
, передавая в качестве аргумента полное имя файла, в котором содержится ваш документ.

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

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

Яманов Александр
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