Теперь несложно разобраться с примером 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<XMLCh> XercesString;
Для выполнения преобразований между строками Xerces и строками, состоящими из стандартных символов, используйте перегруженный статический метод
transcode
из класса
xercesc::XMLString
, который определен в заголовочном файле xercesc/util/XMLString.hpp.
В примере 14.4 определяются две перегруженные вспомогательные функции,
toNative
и
fromNative
, которые используют
transcode
для преобразования строк со стандартными символами в строки
Xerces
и обратно. Каждая функция имеет две версии: одна принимает строку в C-стиле, а другая принимает строку стандартной библиотеки С++. Для выполнения преобразований между строками Xerces и строками со стандартными символами вполне достаточно иметь эти служебные функции; после того как вы определили эти функции, вам уже никогда не потребуется вызывать непосредственно
transcode
.
Пример 14.4. Заголовочный файл xerces_strings.hpp, используемый для выполнения преобразований между строками Xerces и строками со стандартными символами