Question

I'm trying to append a very big subtree using rapidxml in a dirty way, exploiting the value method

rapidxml::xml_node<>* node = allocate_node(rapidxml::node_element, "tree");
node->value("<very><long><subtree></subtree></long></very>");

but it but the angle brackets are expanded into &lt and &gt when I print the document. The clean way would be to manually declare and append every single node and attribute of the subtree, which is pretty boring.

Is there a way to prevent brackets expansion, or can you suggest any other practical way to quickly add a big branch?

Was it helpful?

Solution 2

Ok, I came out with this workaround, automatically creating the structure and appending it:

char txt[] = "<very><long><xml with="attributes"></xml></long></very>";   // or extract from file
rapidxml::xml_document<char> tmp;
tmp.parse<0>(txt);

rapidxml::xml_node<char> *subt = tmp.first_node();
tmp.remove_all_nodes(); // detach, since you can't have more than one parent

appendHere.append_node(subt);

any idea to improve it, maybe to avoid the extra overhead to parse the subtree?

OTHER TIPS

Imho easiest way would be to parse it with new document and then just clone it, something like

void appendLongTree(rapidxml::xml_document<>* document, 
                    rapidxml::xml_node<>* parent,
                    char* value) {
    rapidxml::xml_document<>* new_document = new rapidxml::xml_document<>();
    // if we don't wanna bother about lifetime of the string,
    // save a string in target's document
    new_document.parse<0>(document->allocate_string(value));
    parent->append_node(document->clone_node(new_document->first_node()));
    delete new_document;
}

I don't think it's a big overhead in parsing...

Write a helper function or class, e.g.

#include <iostream>

#include "rapidxml.hpp"
#include "rapidxml_print.hpp"

class Node_Adder
{
public:
  Node_Adder(rapidxml::xml_document<> & doc) : m_doc(doc) { }

  rapidxml::xml_node<> * operator()(rapidxml::xml_node<> * parent,
                                    char const * node_name)
  {
    char * name = m_doc.allocate_string(node_name);
    rapidxml::xml_node<> * child = m_doc.allocate_node(rapidxml::node_element, name);
    parent->append_node(child);
    return child;
  }
protected:
private:
  rapidxml::xml_document<> & m_doc;
};


void stackoverflow()
{
  rapidxml::xml_document<> doc;
  rapidxml::xml_node<char> * decl = doc.allocate_node(rapidxml::node_declaration);
  decl->append_attribute(doc.allocate_attribute("version", "1.0"));
  decl->append_attribute(doc.allocate_attribute("encoding", "UTF-8"));
  doc.append_node(decl);
  rapidxml::xml_node<> * root = doc.allocate_node(rapidxml::node_element, "root");
  doc.append_node(root);

  Node_Adder add(doc);
  add(add(add(root, "very"), "long"), "subtree");

  rapidxml::print(std::ostreambuf_iterator<char>(std::cout), doc);
}

which prints

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <very>
                <long>
                        <subtree/>
                </long>
        </very>
</root>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top