XML сериализация / десериализация в C ++ - PullRequest
0 голосов
/ 31 августа 2011

У меня есть набор классов C ++, которые сериализуются в XML. Ницца и денди. Мне нужно иметь процедуру десериализации для инициализации тех же классов из потоков XML.

Что мне не ясно, так это как анализировать поток XML, используя expat или tinyXML, которые являются анализаторами потока, чтобы узнать, какой XML передать в экземпляр для использования, чтобы инициализировать себя.

Как это традиционно делается? Разобрать файл XML и создать соответствующие классы очень просто, так как анализируется XML, но десериализовать функцию-член, как это выглядит?

Спасибо Реза

Ответы [ 2 ]

0 голосов
/ 31 августа 2011

Когда вы сериализуете свои классы в XML, каждый узел должен содержать некоторый идентификатор того, каков их тип времени выполнения.Для десериализации создайте std::unordered_map, который сопоставляет эти идентификаторы типов с заводскими функциями для каждого типа.Это потребует, чтобы функции фабрики имели одинаковую сигнатуру, поэтому вам нужно будет извлечь все сериализуемые классы из общего интерфейса.Понизьте значение возврата фабричной функции во время выполнения в зависимости от идентификатора типа.Создайте сеттеры / геттеры для доступа к каждому атрибуту и ​​значению, которое может иметь конкретный тип узла.

Если вы используете парсер DOM, все может быть немного проще, потому что у вас есть вся информация об узле, когда вы сталкиваетесь с ним,

С помощью синтаксического анализатора SAX вам придется создавать классы дочерних узлов и устанавливать атрибуты и значения для каждого узла, когда вы сталкиваетесь с ними.Ваш синтаксический анализатор XML должен разрешать обратные вызовы или виртуальные методы, которые могут быть переопределены, получать уведомления о новых атрибутах и ​​узлах при чтении файла XML.


Или, если вы не возражаете тратить деньги,Самый простой выход - позволить кому-то сделать всю работу за вас.Я никогда не использовал Code Synthesis XSD , но он предназначен именно для того, что вы пытаетесь сделать.

0 голосов
/ 31 августа 2011

Ваш формат сериализации должен включать элемент, который указывает класс сериализуемого объекта.Например, вы можете запустить каждый сериализованный объект XML следующим образом:

<object>
    <class>ClassName</class>
    ... object data here
</object>

Это означает, что каждому из ваших классов C ++ должно быть присвоено уникальное имя строки для записи в XML.

Itне имеет значения, какой парсер XML вы используете.Ваша десериализованная функция должна прочитать имя класса и сопоставить его с реальным классом.В простейшей форме это можно сделать длинной цепочкой операторов if, но, конечно, вы можете придумать более сложные механизмы, если хотите.Зная класс, вы можете создать пустой экземпляр и, предполагая, что все ваши классы наследуются от базового класса, затем вызвать виртуальную функцию fromXML(), которая является чисто виртуальной в базовом классе и реализована во всех ваших подклассах.Метод fromXML() проанализирует остальную часть дерева XML и инициализирует экземпляр объекта в соответствии с данными, прочитанными из него.

...