I am trying to read my vector with tuple and parse it in to a xml file. The writing to the XML file works but he only write the values of the last node. So i get only the same values all time. I found that after the for loop he loosing all existing nodes. Maybe my idea with doc.append_node(root) is wrong?!
#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();
}
Your problem's probably here.
char d = std::get<0>(tuple).key;
key->value(&d, 1);
RapidXML stores the pointer you pass to value(), not the string it points to. So each time ound the loop your "value" points to the same thing - 'd'.
You should use key->value(doc.allocate_string(&d, 1))
to add a copy of the character data to the key. The same, later for node->value
.
Rapidxml is writing wrong characters
It's absolutely the #1 RapidXML gotcha.