Animal result; // Возвратить значение
TiXmlElement* element = animal->FirstChildElement();
// Прочитать элемент клички животного
if (element && strcmp(element->Value(), 'name') == 0) {
// Первым дочерним элементом объекта animal является кличка (элемент
// name'); используйте ее текстовое значение для установки клички
// в объекте result
result.setName(textValue(element));
} else {
throw runtime_error('no name attribute');
}
// Прочитать элемент вида животного
element = element->NextSiblingElement();
if (element && strcmp(element->Value(), species') == 0) {
// Вторым дочерним элементом animal является вид животного
// (элемент 'species'); используйте его текстовое значение для
// установки вида в объекте result
result.setSpecies(textValue(element));
} else {
throw runtime_error(''no species attribute');
}
// Прочитать элемент даты рождения
element = element->NextSiblingElement();
if (element && strcmp(element->Value(), 'dateOfBirth') == 0) {
// Третьим дочерним элементом animal является дата рождения
// (элемент 'dateOfBirth'));
// используйте его текстовое значение для установки даты
// рождения в объекте result
result.setDateOfBirth(textValue(element));
} else {
throw runtime_error('no dateOfBirth attribute');
}
// Прочитать элемент ветеринара
element = element->NextSiblingElement();
if (strcmp(element->Value(), 'veterinarian') == 0) {
// Четвертым дочерним элементом animal является ветеринар (элемент
// 'veterinarian'); используйте его для конструирования объекта
// Contact и установки имени ветеринара в объекте result
result.setVeterinarian(nodeToContact(element));
} else {
throw runtime_error('no veterinarian attribute');
}
// Прочитать элемент дрессировщика
element = element->NextSiblingElement();
if (strcmp(element->Value(), 'trainer') == 0) {
// Пятым элементом animal является дрессировщик (элемент 'trainer');
// используйте его для конструирования объекта
// Contact и установки дрессировщика в объекте result
result.setTrainer(nodeToContact(element));
} else {
throw runtime_error('no trainer attribute');
}
// Убедиться в отсутствии других дочерних элементов
element = element->NextSiblingElement();
if (element != 0) {
throw runtime_error(
string('unexpected element:') + element->Value()
);
}
return result;
}
int main() {
using namespace std;
try {
vector<Animal> animalList;
// Обработать 'animals.xml'
TiXmlDocument doc('animals.xml');
if (!doc.LoadFile())
throw runtime_error('bad parse');
// Убедиться, что корневым является список животных
TiXmlElement* root = doc.RootElement();
if (strcmp(root->Value(), 'animalList') != 0) {
throw runtime_error(string('bad root: ') + root->Value());
}
// Просмотреть все дочерние элементы корневого элемента, заполняя
// список животных
for (TiXmlElement* animal = root->FirstChildElement();
animal; animal = animal->NextSiblingElement()) {
animalList.push_back(nodeToAnimal(animal));
}
// Напечатать клички животных
for (vector<Animal>::size_type i = 0, n = animalList.size(); i < n; ++i) {
cout << animalList[i] << '
';
}
} catch (const exception& e) {
cout << e.what() << '
';
return EXIT_FAILURE;
}
}
TinyXml (буквально «крошечный XML») очень хорошо подходит в тех случаях, когда требуется выполнять несложную обработку документов XML. Дистрибутив исходных текстов этой библиотеки небольшой, ее легко построить и интегрировать в проекты, и она имеет очень простой интерфейс. Она также имеет очень либеральную лицензию. Главными ограничениями TinyXml являются невосприимчивость к пространствам имен XML, невозможность контроля DTD или схемы, а также невозможность анализа документов XML с внутренним DTD. Если вам требуется какая-то из этих функций или какая-нибудь XML-технология, как, например, XPath или XSLT, то необходимо воспользоваться другими библиотеками, рассмотренными в данной главе.