我不被允许创建新标签'tinyxml2',这就是为什么我使用标签'tinxxml',但我使用的是'tinyxml2'
我正在尝试将子树元素插入到现有的XML文件中。我的问题是,在运行程序并检查XML文件之后,文档中根本不存在子树。在原始代码中,我还在加载和保存文件时检查错误,因此这些函数没有问题,它们工作正常。我尝试了几种不同的方法,通过使用UserList.NewElement(*name*)
-函数添加一个元素也很好。现在我想插入一个文本变量的整个子树。。。
我的最新方法如下(在不检查LoadFile
和SaveFile
的情况下简化):
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文件包含其原始内容,但是解析的子树仍然丢失。。。非常感谢您提供的任何解决方案/帮助/建议。
TinyXML-2在XMLDocument中存储的内存池中为其节点(XMLNode)分配内存。这修复了TinyXML-1中存在的内存碎片问题。
副作用是元素不能从一个XMLDocument移动到另一个。它们只能被复制。遗憾的是,TinyXML-2目前不支持深度复制(树复制),因此无法执行您想要的操作。(尽管github网站要求提供深度复制。)
顺便说一句,我希望您编写的代码断言(在调试模式下)或崩溃,因为myNewUser与UserList位于不同的内存池中。
我使用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;
}
截至今日:
// 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));