C++. Сборник рецептов
Шрифт:
void setName(const std::string& name) { name_ = name; }
void setSpecies(const std::string& species) { species_ = species; }
void setDateOfBirth(const std::string& dob) {
dob_ = boost::gregorian::from_string(dob);
}
void setVeterinarian(const Contact& vet) { vet_ = vet; }
void setTrainer(const Contact& trainer) { trainer_ = trainer; }
private:
std::string name_;
std::string species_;
boost::gregorian::date dob_;
Contact vet_;
Contact trainer_;
};
//
Сравнение на равенство двух объектов Animal; используется в рецепте 14.9
// (для полноты следует также определить operator!=)
bool operator==(const Animal& lhs, const Animal& rhs) {
return lhs.name == rhs.name && lhs.species == rhs.species &&
lhs.dateOfBirth == rhs.dateOfBirth &&
lhs.veterinarian == rhs.veterinarian &&
lhs.trainer == rhs.trainer;
}
// Записывает объект Animal в поток ostream
std::ostream& operator<<(std::ostream& out, const Animal& animal) {
out << "Animal {\n"
<< " name=" << animal.name << ";\n"
<< " species=" << animal.species << ";\n"
<< date-of-birth=" << animal.dateOfBirth << ";\n"
<< " veterinarian=" << animal.veterinarian << ";\n"
<< " trainer=" << animal.trainer << ";\n"
<< "}";
return out;
}
#endif // #ifndef ANIMALS_HPP_INCLUDED
Пример 14.3. Синтаксический анализ animals.xml с помощью TinyXml
#include <exception>
#include <iostream> // cout
#include <stdexcept> // runtime_error
#include <cstdlib> // EXIT_FAILURE
#include <cstring> // strcmp
#include <vector>
#include <tinyxml.h>
#include "animal.hpp"
using namespace std;
// Извлекает текстовое содержимое элемента XML
const char* textValue("TiXmlElement* e) {
TiXmlNode* first = fi->FirstChild;
if (first != 0 && first == e->LastChild &&
first->Type == TiXmlNode::TEXT) {
//
элемент «е» имеет один дочерний элемент типа TEXT;
// возвратить дочерний элемент
return first->Value;
} else {
throw runtime_error(string("bad ") + e->Value + " element");
}
}
// Конструирует объект класса Contact из элементов ветеринара или
// дрессировщика ("veterinarian" или "trainer")
Contact nodeToContact(TiXmlElement* contact) {
using namespace std;
const char *name, *phone;
if (contact->FirstChild == 0 &&
(name = contact->Attribute("name")) &&
(phone = contact->Attribute("phone"))) {
// Элемент contact не имеет дочерних элементов и имеет атрибуты имени
// и телефона ("name" и "phone"); используйте эти значения для
// конструирования объекта Contact
return Contact(name, phone);
} else {
throw runtime_error(string("bad ") + contact->Value + " element");
}
}
// Конструирует объект Animal из элемента животного ("animal")
Animal nodeToAnimal(TiXmlElement* animal) {
using namespace std;
// Убедиться, что animal соответствует элементу "animal"
if (strcmp(animal->Value, "animal") != 0) {
throw runtime_error(string("bad animal: ") + animal->Value);
}
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 является вид животного
Поделиться с друзьями: