Теперь несложно разобраться с примером 14.3. Во-первых, функция textValue()извлекает текстовое содержимое из элементов, содержащих только текст, например name, speciesили dateOfBirth. В этом случае данная функция сначала убеждается, что имеется только один дочерний элемент и что он является текстовым узлом. Она затем получает текст дочернего элемента, вызывая метод Value(), который возвращает текстовое содержимое текстового узла или узла комментария, имя тега узла элемента и имя файла корневого узла.
На следующем шаге функция nodeToContact()получает узел, соответствующий элементу veterinarianили trainer, и конструирует объект Contactиз значений атрибутов nameи phone, получаемых с помощью метода Attribute().
Аналогично функция nodeToAnimal()получает узел, соответствующий элементу животного element, и конструирует объект Animal. Это делается путем прохода по дочерним узлам с помощью метода NextSiblingElement(), извлекая при этом содержащиеся в каждом элементе данные и устанавливая соответствующее свойство объекта Animal. Данные извлекаются, используя функцию textValue()для элементов name, speciesи dateOfBirthи функцию nodeToContact()для элементов veterinarianи trainer.
В функции mainя сначала конструирую объект TiXmlDocumentсоответствующий файлу animals.xml , и выполняю его синтаксический разбор с помощью метода LoadFile(). Затем я получаю элемент TiXmlElement, соответствующий корню документа, вызывая метод RootElement(). На следующем шаге я просматриваю все дочерние узлы корневого элемента, конструируя объект Animalиз каждого элемента animalс помощью функции nodeToAnimal(). Наконец, я прохожу по всем объектам Animal, записывая их в стандартный вывод.
В примере 14.3 не проиллюстрирована одна функция библиотеки TinyXml, а именно метод SaveFile()класса TiXmlDocument, который записывает в файл документ, представляемый объектом TiXmlDocument. Это позволяет выполнить синтаксический разбор документа XML, модифицировать его, используя интерфейс DOM, и сохранить модифицированный документ. Документ TiXmlDocumentможно создать даже с чистого листа и затем сохранить его на диске.
// Создать документ hello.xml, состоящий
// из единственного элемента "hello"
TiXmlDocument doc;
TiXmlElement root("hello");
doc.InsertEndChild(root);
doc.SaveFile("hello.xml");
Смотри также
Рецепты 14.3 и 14.4.
14.2. Работа со строками Xerces
Проблема
Требуется обеспечить надежную и простую работу со строками с расширенным набором символов, используемыми библиотекой Xerces. В частности, необходимо уметь сохранять строки, возвращаемые функциями библиотеки Xerces, а также выполнять преобразования между строками Xerces и строками стандартной библиотеки С++.
Решение
Сохранять строки с расширенным набором символов, возвращаемые функциями библиотеки Xerces, можно с помощью шаблона std::basic_string, специализированного типом с расширенным набором символов XMLChбиблиотеки Xerces.
typedef std::basic_string XercesString;
Для выполнения преобразований между строками Xerces и строками, состоящими из стандартных символов, используйте перегруженный статический метод transcode()из класса xercesc::XMLString, который определен в заголовочном файле xercesc/util/XMLString.hpp .
В примере 14.4 определяются две перегруженные вспомогательные функции, toNativeи fromNative, которые используют transcodeдля преобразования строк со стандартными символами в строки Xercesи обратно . Каждая функция имеет две версии: одна принимает строку в C-стиле, а другая принимает строку стандартной библиотеки С++. Для выполнения преобразований между строками Xerces и строками со стандартными символами вполне достаточно иметь эти служебные функции; после того как вы определили эти функции, вам уже никогда не потребуется вызывать непосредственно transcode.
Пример 14.4. Заголовочный файл xerces_strings.hpp, используемый для выполнения преобразований между строками Xerces и строками со стандартными символами
#ifndef XERCES_STRINGS_HPP_INCLUDED
#define XERCES_STRINGS_HPP_INCLUDED
#include
#include
#include
typedef std::basic_string XercesString;
// Преобразует строку со стандартными символами
// в строку с расширенным набором символов
inline XercesString fromNative(const char* str) {
boost::scoped_array ptr(xercesc::XMLString::transcode(str));
Читать дальше