c++ 使用tinyxml2将文本中的子树插入现有XML文件

8hhllhi2  于 2023-03-20  发布在  其他
关注(0)|答案(3)|浏览(158)

不允许我创建新标记“tinyxml 2”,这就是我使用标记“tinyxml”的原因,但我使用的是“tinyxml 2”!

我试图插入一个子树元素到一个现有的XML文件。我的问题是,在运行程序并检查XML文件后,子树根本不存在于文档中。在原始代码中,我也在加载和保存文件时检查错误,所以这些函数没有问题,它们工作正常。我尝试了几种不同的方法,也通过使用UserList.NewElement(*name*)-函数添加了单个元素,也工作正常。现在我想从文本变量插入整个子树...
我的最新方法如下所示(简化后没有检查LoadFileSaveFile):

tinyxml2::XMLDocument UserList;
UserList.LoadFile(*Path*);

const char* XMLText = "<user name=\"test-user\" gender=\"male\"><ability description=\"I_can_do_magic\" /></user>";

tinyxml2::XMLDocument TestParse;
TestParse.Parse(XMLText);
tinyxml2::XMLElement* myNewUser = TestParse.RootElement();
UserList.FirstChildElement( "magicians" )->InsertEndChild(myNewUser);
UserList.SaveFile(*Path*);

顺便说一句...当我尝试使用tinyxml2::XMLDocument UserList解析我的XMLText时,运行程序后保存的XML文件将为空。这意味着在尝试这样做时,既不会保存原始XML文档内容,也不会保存新解析的子树。这一事实使我使用了第二个tinyxml2::XMLDocument TestParse。现在保存的XML文件包含其原始内容,然而,解析后的子树仍然缺失...非常感谢您的任何解决方案/帮助/建议。

toe95027

toe950271#

TinyXML-2在存储于XMLDocument中的内存池中为它的节点(XMLNode)分配内存。这解决了TinyXML-1中存在的内存碎片问题。
副作用是元素不能从一个XMLDocument移动到另一个XMLDocument,只能复制。遗憾的是,TinyXML-2目前不支持深度复制(树复制),所以不能做你想做的事情。(尽管github站点要求深度复制。)
顺便说一句,我希望您编写的代码Assert(在调试模式下)或崩溃,因为myNewUser与UserList位于不同的内存池中。

c8ib6hqw

c8ib6hqw2#

我使用TinyXML-2的XMLVisitor编写了一个深度复制函数,希望这对您有用:

#include <stack>
#include "tinyxml2.h"
using namespace tinyxml2;
class MyXMLVisitor: public XMLVisitor
{
public:
    MyXMLVisitor(XMLDocument *doc)
        : m_doc(doc)
    {
    }

    virtual bool VisitEnter (const XMLElement &el, const XMLAttribute *attr)
    {
        XMLElement *new_el = m_doc->NewElement(el.Name());
        m_elementStack.push(new_el);
        return true;
    }

    virtual bool Visit(const XMLText &txt)
    {
        m_elementStack.top()->SetText(txt.Value());
        return true;
    }

    virtual bool VisitExit (const XMLElement &el)
    {
        XMLElement *top_el = m_elementStack.top();
        m_elementStack.pop();
        if (m_elementStack.empty()) {
            m_element = top_el;
            return false;
        }
        else {
            m_elementStack.top()->InsertEndChild(top_el);
            return true;
        }
    }

    std::stack<XMLElement*> m_elementStack;
    XMLDocument *m_doc;
    XMLElement *m_element;
};

XMLElement* DeepCopyElement(XMLDocument &doc, const XMLElement *el)
{
    MyXMLVisitor my_visitor(&doc);
    el->Accept(&my_visitor);
    return my_visitor.m_element;
}

int main(int argc, char* argv[])
{
    XMLDocument doc;
    doc.LoadFile( "test.xml" );

    XMLElement *modulesElement = doc.FirstChildElement("modules");
    XMLElement *moduleElement = modulesElement->FirstChildElement("module");
    modulesElement->InsertEndChild(DeepCopyElement(doc, moduleElement));

    doc.SaveFile("test_out.xml");
    return 0;
}
bejyjqdl

bejyjqdl3#

截至今日:

// all three initialized elsewhere
XMLDocument xd; // document into which to instert
XMLElement *pSubtreeToInsert; // subtree to insert - doesn't matter which document it is part of
XMLElement *pInsertionPoint; // element that is going to be the subtree parent, in my case part of xd

XMLNode *pInsertedClone = pInsertionPoint->InsertEndChild(pSubtreeToInsert->DeepClone(&xd));

相关问题