Пример 14.24 использует Pathan 1, который реализует рекомендации XPath 1.0; библиотекой Xalan в настоящее время поддерживается именно эта версия. Pathan 2, который в настоящее время доступен в бета-версии, обеспечивает предварительную реализацию рекомендаций XPath 2.0. Pathan 2 представляет собой более точную реализацию стандарта XPath; я рекомендую использовать Pathan 2 вместо Pathan 1, как только станет доступна не бета-версия.
Смотри также
Рецепт 14.7.
14.9. Применение XML для сохранения и восстановления набора объектов
Проблема
Требуется иметь возможность сохранения набора объектов C++ в документе XML и считывания их потом обратно в память.
Решение
Используйте библиотеку Boost Serialization. Эта библиотека позволяет сохранять и восстанавливать объекты, используя классы, называемые архивами. Для использования этой библиотеки вы должны сначала сделать каждый из ваших классов сериализуемым (serializable), что просто означает возможность записи экземпляров класса в архив (это называется сериализацией) и их обратного считывания в память (это называется десериализацией). Затем на этапе выполнения вы можете сохранить ваши объекты в архиве XML, используя оператор
<<
, и восстановить их, используя оператор
>>
.
Чтобы сделать класс сериализуемым, добавьте шаблон функции-члена
serialize
со следующей сигнатурой.
template<typename Archive>
void serialize(Archive& ar, const unsigned int version);
В реализации
serialize
необходимо обеспечить запись каждого данного-члена класса в указанный архив в виде пары «имя-значение», используя оператор
&
. Например, если вы хотите сериализовать
и десериализовать экземпляры класса
Contact
из примера 14.2, добавьте функцию-член
serialize
, как это сделано в примере 14.25.
Пример 14.25. Добавление поддержки сериализации в класс Contact из примера 14.2
#include <boost/serialization/nvp.hpp> // пара "имя-значение"
class Contact {
...
private:
friend class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int version) {
// Записать (или считать) каждое данное-член в виде пары имя-значение
using boost::serialization::make_nvp;
ar & make_nvp("name", name_);
ar & make_nvp("phone", phone_);
}
...
};
Аналогично можно обеспечить сериализацию класса
Animal
из примера 14.2, как это сделано в примере 14.26.
Пример 14.26. Добавление поддержки сериализации для класса Animal из примера 14.2
...
// Включить поддержку сериализации для boost::gregorian::date
void serialize(Archive& ar, const unsigned int version) {
// Записать (или считать) каждое данное-член в виде пары имя-значение
using boost::serialization::make_nvp;
ar & make_nvp("name", name_);
ar & make_nvp("species", species_);
ar & make_nvp("dateOfBirth", dob_);
ar & make_nvp("veterinarian", vet_);
ar & make_nvp("trainer", trainer_);
}
...
};
Теперь вы можете сериализовать Animal, создавая архив XML типа
boost::archive::xml_oarchive
и записывая информацию о животном в архив, используя оператор
<<
. Конструктор
xml_oarchive
в качестве аргумента принимает
std::ostream
; часто этим аргументом будет поток вывода, используемый для записи в файл, однако в общем случае для записи данных может использоваться ресурс любого типа. После сериализации экземпляра
Animal
его можно считать обратно в память, конструируя архив XML типа boost::archive::
xml_iarchive
, подключая его к тому же самому ресурсу, который использовался первым архивом, и применяя оператор