2014-09-02 2 views
0

새 태그 'tinyxml2'를 만들 수 없기 때문에 'tinyxml'태그를 사용하고 있는데 'tinyxml2'를 사용하고 있습니다!tinyxml2를 사용하여 기존 XML 파일에 텍스트의 하위 트리 삽입하기

기존 XML 파일에 하위 트리 요소를 삽입하려고합니다. 내 문제는 프로그램을 실행하고 XML 파일을 검사 한 후 하위 트리가 문서 내에 존재하지 않는다는 것입니다. 원래 코드에서 파일을로드하고 저장하는 동안 오류를 확인하기 때문에 이러한 함수에 문제가 없으므로 제대로 작동합니다. 나는 몇 가지 다른 접근법을 시도하고 또한 UserList.NewElement(*name*) 함수를 사용하여 단일 요소를 추가하는 것도 잘 동작합니다. 그런데

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

... 언제 : 지금은

내 최신 방법은 (LoadFileSaveFile을 확인하지 않고 간체) 다음과 같습니다 ... 텍스트 변수에서 전체 하위 트리를 삽입 할 나는 내 XMLText을 사용하여 tinyxml2::XMLDocument UserList을 사용하여 구문 분석을 시도했지만 프로그램을 실행 한 후 저장된 XML 파일은 비어있게됩니다. 즉, 원본 XML 문서 내용이나 새로 파싱 된 하위 트리가이 작업을 시도 할 때 저장되지 않습니다. 이 사실은 두 번째로 tinyxml2::XMLDocument TestParse을 사용하게했습니다. 이제는 XML 파일이 원래 내용을 포함하여 저장되지만 구문 분석 된 하위 트리는 여전히 누락되었습니다 ... 솔루션/도움말/조언을 주셔서 대단히 감사드립니다.

답변

1

TinyXML-2는 XMLDocument에 저장된 메모리 풀에서 해당 노드 (XMLNode)에 메모리를 할당합니다. 이것은 TinyXML-1에있는 메모리 단편화 문제를 수정합니다.

부작용은 하나의 XMLDocument에서 다른 XMLDocument로 요소를 이동할 수 없다는 것입니다. 사본은 복사 만 할 수 있습니다. 유감스럽게도, TinyXML-2는 현재 딥 카피 (트리 복사본)를 지원하지 않으므로 원하는 것을 할 수 없습니다. (깊은 복사본은 github 사이트에서 요청한 것입니다.)

myNewUser는 UserList의 다른 메모리 풀에 있기 때문에 (디버그 모드에서) 어설 션하기 위해 작성한 코드 나 충돌하는 것은 예상됩니다.

1

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

답장을 보내 주셔서 대단히 감사합니다. 그러나 제 경우에는 조금 늦었습니다. tinyxml을 사용하지 않음으로써 그 때의 해결책을 찾았습니다. 이 솔루션은 다른 사람들을 도울 수 있습니다 ... – Dino

관련 문제