писать в XML с помощью RapidXML

Я пытаюсь прочитать свой вектор с помощью кортежа и разобрать его в файл xml. Запись в файл XML работает, но он записывает только значения последнего узла. Поэтому я всегда получаю только одни и те же значения. Я обнаружил, что после цикла for он теряет все существующие узлы. Может быть, моя идея с doc.append_node(root) неверна?!

    #include "XmlHandle.h"
    #include <rapidxml/rapidxml.hpp>
    #include "rapidxml/rapidxml_print.hpp"
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <stdlib.h>
    #include <sstream>

    using namespace rapidxml;

    XmlHandle::WriteToXml(std::vector<std::tuple<Key, Tone>> vector)
    {
        xml_document<> doc;
        xml_node<>* decl = doc.allocate_node(node_declaration);
        //adding attributes at the top of our xml
        decl->append_attribute(doc.allocate_attribute("version", "1.0"));
        decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
        doc.append_node(decl);
        //creating a pointer for the root note "NoteList"
        xml_node<> *root = doc.allocate_node(node_element, "NoteList");

        //iterating through our vector 
        for (std::tuple<Key, Tone> tuple : vector)
        {
            //creating the nodes tuple and key
            xml_node<> *tuple1 = doc.allocate_node(node_element, "Tuple");
            xml_node<> *key = doc.allocate_node(node_element, "Key");
            //getting the char of key saving in d
            char d = std::get<0>(tuple).key;
            //creating a pointer on d
            key->value(&d, 1);
            const char *name = std::string("test").c_str();
            //creating a new node element Tone
            xml_node<> *ToneNode = doc.allocate_node(node_element, "Tone");
            //adding the element to tuple1
            tuple1->append_node(ToneNode);
            //adding the note element Frequency
            xml_node<> *Frequency = doc.allocate_node(node_element, "Frequency");
            float FrequencyFloat = std::get<1>(tuple).frequency;
            std::string FrequencyString = std::to_string(FrequencyFloat);
            //setting the value from frequency
            Frequency->value(FrequencyString.c_str());
            tuple1->append_node(Frequency);
            xml_node<> *Node = doc.allocate_node(node_element, "Node");
            char * NodeValuePinter = (char*)&std::get<1>(tuple).tone;
            char *charPinter = &std::get<1>(tuple).tone;
            Node->value(charPinter, 1);
            ToneNode->append_node(Node);
            tuple1->append_node(key);
            //adding tuple to our root
            root->append_node(tuple1);

        }
        doc.append_node(root);
        std::string xml_as_string;
        rapidxml::print(std::back_inserter(xml_as_string), doc);
        std::ofstream fileStored("file_stored.xml");
        fileStored << xml_as_string;
        fileStored.close();
        doc.clear();
    }

person Julian K.    schedule 03.12.2018    source источник
comment
Это много кода. Можете ли вы представить свой минимально воспроизводимый пример?   -  person Lightness Races in Orbit    schedule 03.12.2018
comment
Это также много указателей. Убедитесь, что вы правы в отношении семантики владения всем, что вы добавляете.   -  person Lightness Races in Orbit    schedule 03.12.2018
comment
Просто отметим, что это противоположно «анализу». Разбор преобразует текстовое представление в структуру данных. Вы идете другим путем ;)   -  person Roddy    schedule 06.12.2018


Ответы (1)


Ваша проблема, вероятно, здесь.

        char d = std::get<0>(tuple).key;
        key->value(&d, 1);

RapidXML сохраняет указатель, который вы передаете в value(), а не строку, на которую он указывает. Таким образом, каждый раз, когда вы проходите цикл, ваше «значение» указывает на одно и то же — «d».

Вы должны использовать key->value(doc.allocate_string(&d, 1)), чтобы добавить копию символьных данных в ключ. То же, позже для node->value.

Rapidxml пишет неправильные символы

Это абсолютная ошибка RapidXML №1.

person Roddy    schedule 06.12.2018