Rapidxml: добавление поддерева непосредственно в качестве значения

Я пытаюсь добавить очень большое поддерево, используя rapidxml грязным способом, используя метод value

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

но это, но угловые скобки раскрываются в &lt и &gt, когда я печатаю документ. Чистым способом было бы вручную объявить и добавить каждый отдельный узел и атрибут поддерева, что довольно скучно.

Есть ли способ предотвратить расширение скобок или вы можете предложить какой-либо другой практический способ быстро добавить большую ветку?


person Cavaz    schedule 12.10.2012    source источник


Ответы (3)


Имхо, самым простым способом было бы проанализировать его с помощью нового документа, а затем просто клонировать его, что-то вроде

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;
}

Я не думаю, что это большие накладные расходы при разборе...

person Artjom Brehhunov    schedule 26.10.2012

Хорошо, я нашел этот обходной путь, автоматически создав структуру и добавив ее:

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);

есть идеи по его улучшению, может быть, чтобы избежать дополнительных накладных расходов на разбор поддерева?

person Cavaz    schedule 15.10.2012

Напишите вспомогательную функцию или класс, например.

#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);
}

который печатает

<?xml version="1.0" encoding="UTF-8"?>
<root>
        <very>
                <long>
                        <subtree/>
                </long>
        </very>
</root>
person MadScientist    schedule 12.10.2012
comment
ну, это был простой пример. Настоящее поддерево имеет несколько ветвей и атрибутов... Моя цель состояла в том, чтобы найти способ грубо вырезать и вставить текст без ручного управления всей структурой. - person Cavaz; 15.10.2012