Как вставить новый узел в xml_document, используя RapidXml для C++, используя строки?

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

Я хочу добавить узел в src2 внутри дерева в src, используя RapidXml. Я делаю это:

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 */

Что ж, отлично, он компилируется, но при запуске я получил эту ужасную ошибку:

void rapidxml::xml_node::append_node(rapidxml::xml_node*) [с Ch = char]: Утверждение `child && !child->parent() && child->type() != node_document' не удалось. Прервано

Я не знаю, как это сделать. Проблема проста, мне нужно добавить узел в дерево (xml), но у меня есть строки.

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

Есть ли способ сделать то, что мне нужно, простым способом?

Спасибо.


person Andry    schedule 12.01.2011    source источник


Ответы (1)


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

Выход:

<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>
person Eugen Constantin Dinca    schedule 13.01.2011
comment
Спасибо за ваш ответ, но это точно работает. Мне нужно проанализировать обе строки, чтобы получить два узла. Я не могу упустить ни одно из этих двух требований. Выделение узлов делает их дочерними по отношению к тому, который я хочу добавить, и пример работает, но это не моя ситуация. Мне жаль. В любом случае спасибо за помощь :) - person Andry; 13.01.2011
comment
@Andry: см. обновление. Я пытался подчеркнуть, что вставляемые узлы должны быть выделены из того же пула памяти/xml_document, в который вы хотите их добавить. - person Eugen Constantin Dinca; 13.01.2011
comment
Евгений, спасибо. Это хорошее решение... Я не думал об этом... однако мне нужно больше, понимаете, поэтому я могу сосредоточиться только на узле, мой реальный случай заключается в том, что узел ‹nodex› может содержать другие узлы, и, не зная внутренней структуры узла, я хочу иметь возможность добавлять в дерево всю иерархию. Ну, я думаю, что я должен добавить эти узлы вручную, перемещаясь по дереву, однако вы были действительно полезны. Вы заслуживаете правильного ответа. :) Спасибо :) - person Andry; 13.01.2011
comment
Ну что ж... знаете ли вы способ назначить пул памяти всему дереву, чтобы я мог назначить пул памяти xmldoc для xmlseg??? - person Andry; 13.01.2011
comment
@Andry: ознакомьтесь с документацией по классу memory_pool здесь rapidxml.sourceforge.net/ . Хотя для объединения целых деревьев вы можете использовать метод xml_document::clone_node. Посмотрите модифицированный пример. - person Eugen Constantin Dinca; 13.01.2011