3
std::string src = "<xml><node1>aaa</node1><node2>bbb</node2><node1>ccc</node1></xml>";
std::string src2 = "<nodex>xxx</nodex>";

I want to append the node in src2 inside the tree in src using RapidXml I do this:

xml_document<> xmldoc;
xml_document<> xmlseg;
std::vector<char> s(src.begin(), src.end());
std::vector<char> x(src2.begin(), src2.end());
xmldoc.parse<0>(&s[0]);
xmlseg.parse<0>(&x[0]);
xml_node<>* a = xmlseg.first_node(); /* Node to append */
xmldoc.first_node("xml")->append_node(a); /* Appending node a to the tree in src */

Well, great it compiles, but when running I got this horrible error:

void rapidxml::xml_node::append_node(rapidxml::xml_node*) [with Ch = char]: Assertion `child && !child->parent() && child->type() != node_document' failed. Aborted

I don't know how to do. The problem is simple I need to append a node to a tree (xml) but I have strings.

I guess this happens because I'm trying to insert a node of a tree into another tree... only nodes allocated for a given tree can be added to that tree... this sucks...

Is there a way I can do what I need in a simple way?

Thank you.

Andry
  • 14,281
  • 23
  • 124
  • 216

1 Answers1

3
#include <iostream>
#include <string>
#include <vector>

#include <rapidxml.hpp>
#include <rapidxml_print.hpp>

int main(){
std::string src = "<xml><node1>aaa</node1><node2>bbb</node2><node1>ccc</node1></xml>";
std::string src2 = "<nodex><nodey>xxx</nodey></nodex>";
//std::string src2 = "<nodex>xxx</nodex>";
rapidxml::xml_document<> xmldoc;
rapidxml::xml_document<> xmlseg;

std::vector<char> s( src.begin(), src.end() );
s.push_back( 0 ); // make it zero-terminated as per RapidXml's docs

std::vector<char> x(src2.begin(), src2.end());
x.push_back( 0 ); // make it zero-terminated as per RapidXml's docs

xmldoc.parse<0>( &s[ 0 ] );
xmlseg.parse<0>( &x[0] );

std::cout << "Before:" << std::endl;
rapidxml::print(std::cout, xmldoc, 0);

rapidxml::xml_node<>* a = xmlseg.first_node(); /* Node to append */

rapidxml::xml_node<> *node = xmldoc.clone_node( a );
//rapidxml::xml_node<> *node = xmldoc.allocate_node( rapidxml::node_element, a->name(), a->value() );
xmldoc.first_node("xml")->append_node( node ); /* Appending node a to the tree in src */

std::cout << "After :" << std::endl;
rapidxml::print(std::cout, xmldoc, 0); 
}

Output:

<xml>
        <node1>aaa</node1>
        <node2>bbb</node2>
        <node1>ccc</node1>
</xml>

After :
<xml>
        <node1>aaa</node1>
        <node2>bbb</node2>
        <node1>ccc</node1>
        <nodex>
                <nodey>xxx</nodey>
        </nodex>
</xml>
Eugen Constantin Dinca
  • 8,632
  • 2
  • 28
  • 50
  • Thank you for your answer but that works for sure. I need to parse both strings in order to get two nodes. I cannot miss neither one of these two requirements. Allocating nodes makes them children of the one I want to perform appending, and the example works, but this is not my situation. I'm sorry. Thanks anyway for your help :) – Andry Jan 13 '11 at 00:37
  • @Andry: see update. The point I was trying to make was that nodes to be inserted need to be allocated from the same memory pool/xml_document that you want to add them to. – Eugen Constantin Dinca Jan 13 '11 at 01:50
  • Eugen, thank you. It is a good solution... I didn't think about it... however still I need more, you see, so I can only focus on a node, my real case is that node may contain other nodes, and, without knowing the node internal structure, I want to be able to add the entire hierarchy to the tree. Well, I think I must add those nodes manually navigating the tree, however you were really helpful. You deserve the right answer. :) Thankyou :) – Andry Jan 13 '11 at 08:11
  • Ah well... do you know a way to assign a memory pool to an entire tree so that I can assign the mempool of xmldoc to xmlseg??? – Andry Jan 13 '11 at 08:20
  • @Andry: Check out the documentation for the `memory_pool` class here http://rapidxml.sourceforge.net/manual.html#classrapidxml_1_1memory__pool . Although for splicing in entire trees you can use the xml_document::clone_node. Check out the modified example. – Eugen Constantin Dinca Jan 13 '11 at 16:48