Чтение онлайн

ЖАНРЫ

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

parser->parseURI("animals.xml");

DOMElement* animalList = doc->getDocumentElement;

// Создать XPath-выражение.

auto_ptr<XPathEvaluator>

evaluator(XPathEvaluator::createEvaluator);

auto_ptr<XPathNSResolver>

resolver(evaluator->createNSResolver(animalList));

auto_ptr<XPathExpression> xpath(

evaluator->createExpression(FromNative(

"animalList/animal[child::name='Herby']" ).c_str, resolver.get

)

);

auto_ptr<XPathEvaluator> evaluator(XPathEvaluator::createEvaluator);

auto_ptr<XPathNSResolver> resolver(evaluator->createNSResolver(animalList));

auto_ptr<XPathExpression> xpath(evaluator->createExpression(

fromNative("animalList/animal[child::name='Herby']").c_str,

resolver.get

));

//
Вычислить выражение.

XPathResult* result = xpath->evaluate(doc,

XPathResult::ORDERED_NODE_ITERATOR_TYPE, 0

);

DOMNode* herby;

if (herby = result->iterateNext) {

animalList->removeChild(herby);

herby->release; // optional

}

// Сконструировать DOMWriter для сохранения animals.xml

DOMPtr<DOMWriter> writer =

static_cast<DOMImplementationLS->(impl)->createDOMWriter;

writer->setErrorHandler(&err);

// Сохранить animals.xml.

LocalFileFormatTarget file("circus.xml");

writer->writeNode(&file, *animalList);

 } catch (const DOMException& e) {

cout << toNative(e.getMessage) << "\n";

return EXIT_FAILURE;

 } catch (const XPathException &e) {

cout << e.getString << "\n";

return EXIT_FAILURE;

 } catch (const exception& e) {

cout << e.what << "\n";

return EXIT_FAILURE;

 }

}

Пример 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

#include <boost/date_time/gregorian/greg_serialize.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("species", species_);

ar & make_nvp("dateOfBirth", dob_);

ar & make_nvp("veterinarian", vet_);

ar & make_nvp("trainer", trainer_);

 }

 ...

Поделиться с друзьями: