mirror of https://github.com/AxioDL/tinyxml2.git
deep copy and clone
This commit is contained in:
parent
1f5ab7cd0b
commit
7085f00e40
23
tinyxml2.cpp
23
tinyxml2.cpp
|
@ -771,6 +771,18 @@ void XMLNode::SetValue( const char* str, bool staticMem )
|
|||
}
|
||||
}
|
||||
|
||||
XMLNode* XMLNode::DeepClone(XMLDocument* document) const
|
||||
{
|
||||
XMLNode* clone = this->ShallowClone(document);
|
||||
if (!clone) return 0;
|
||||
|
||||
for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) {
|
||||
XMLNode* childClone = child->DeepClone(document);
|
||||
TIXMLASSERT(childClone);
|
||||
clone->InsertEndChild(childClone);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
void XMLNode::DeleteChildren()
|
||||
{
|
||||
|
@ -2006,6 +2018,17 @@ void XMLDocument::Clear()
|
|||
}
|
||||
|
||||
|
||||
void XMLDocument::DeepCopy(XMLDocument* target)
|
||||
{
|
||||
TIXMLASSERT(target);
|
||||
TIXMLASSERT(target != this);
|
||||
|
||||
target->Clear();
|
||||
for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) {
|
||||
target->InsertEndChild(node->DeepClone(target));
|
||||
}
|
||||
}
|
||||
|
||||
XMLElement* XMLDocument::NewElement( const char* name )
|
||||
{
|
||||
TIXMLASSERT( sizeof( XMLElement ) == _elementPool.ItemSize() );
|
||||
|
|
26
tinyxml2.h
26
tinyxml2.h
|
@ -53,7 +53,7 @@ distribution.
|
|||
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
|
||||
*/
|
||||
|
||||
#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
|
||||
#if defined( _DEBUG ) || defined (__DEBUG__)
|
||||
# ifndef DEBUG
|
||||
# define DEBUG
|
||||
# endif
|
||||
|
@ -846,6 +846,20 @@ public:
|
|||
*/
|
||||
virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
|
||||
|
||||
/**
|
||||
Make a copy of this node and all of the children
|
||||
of this node.
|
||||
|
||||
If the 'document' is null, then the nodes will
|
||||
be allocated in the current document. If specified,
|
||||
memory will e allocated is the specified document.
|
||||
|
||||
NOTE: This is probably not the correct tool to
|
||||
copy a document, since XMLDocuments can have multiple
|
||||
top level XMLNodes. You probably want XMLDocument::DeepCopy()
|
||||
*/
|
||||
XMLNode* DeepClone( XMLDocument* document ) const;
|
||||
|
||||
/**
|
||||
Test if 2 nodes are the same, but don't test children.
|
||||
The 2 nodes do not need to be in the same Document.
|
||||
|
@ -1787,6 +1801,16 @@ public:
|
|||
/// Clear the document, resetting it to the initial state.
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
Copies this document to a target.
|
||||
The target will be completely cleared before the copy.
|
||||
If you want to copy a sub-tree, see DeepClone.
|
||||
|
||||
NOTE: that the 'target' must be non-null and not
|
||||
the source document.
|
||||
*/
|
||||
void DeepCopy(XMLDocument* target);
|
||||
|
||||
// internal
|
||||
char* Identify( char* p, XMLNode** node );
|
||||
|
||||
|
|
80
xmltest.cpp
80
xmltest.cpp
|
@ -1130,6 +1130,86 @@ int main( int argc, const char ** argv )
|
|||
XMLTest( "Clone and Equal", 4, count );
|
||||
}
|
||||
|
||||
{
|
||||
// Deep Cloning of root element.
|
||||
XMLDocument doc2;
|
||||
XMLPrinter printer1;
|
||||
{
|
||||
// Make sure doc1 is deleted before we test doc2
|
||||
const char* xml =
|
||||
"<root>"
|
||||
" <child1 foo='bar'/>"
|
||||
" <!-- comment thing -->"
|
||||
" <child2 val='1'>Text</child2>"
|
||||
"</root>";
|
||||
XMLDocument doc;
|
||||
doc.Parse(xml);
|
||||
|
||||
doc.Print(&printer1);
|
||||
XMLNode* root = doc.RootElement()->DeepClone(&doc2);
|
||||
doc2.InsertFirstChild(root);
|
||||
}
|
||||
XMLPrinter printer2;
|
||||
doc2.Print(&printer2);
|
||||
|
||||
XMLTest("Deep clone of element.", printer1.CStr(), printer2.CStr(), true);
|
||||
}
|
||||
|
||||
{
|
||||
// Deep Cloning of sub element.
|
||||
XMLDocument doc2;
|
||||
XMLPrinter printer1;
|
||||
{
|
||||
// Make sure doc1 is deleted before we test doc2
|
||||
const char* xml =
|
||||
"<?xml version ='1.0'?>"
|
||||
"<root>"
|
||||
" <child1 foo='bar'/>"
|
||||
" <!-- comment thing -->"
|
||||
" <child2 val='1'>Text</child2>"
|
||||
"</root>";
|
||||
XMLDocument doc;
|
||||
doc.Parse(xml);
|
||||
|
||||
const XMLElement* subElement = doc.FirstChildElement("root")->FirstChildElement("child2");
|
||||
subElement->Accept(&printer1);
|
||||
|
||||
XMLNode* clonedSubElement = subElement->DeepClone(&doc2);
|
||||
doc2.InsertFirstChild(clonedSubElement);
|
||||
}
|
||||
XMLPrinter printer2;
|
||||
doc2.Print(&printer2);
|
||||
|
||||
XMLTest("Deep clone of sub-element.", printer1.CStr(), printer2.CStr(), true);
|
||||
}
|
||||
|
||||
{
|
||||
// Deep cloning of document.
|
||||
XMLDocument doc2;
|
||||
XMLPrinter printer1;
|
||||
{
|
||||
// Make sure doc1 is deleted before we test doc2
|
||||
const char* xml =
|
||||
"<?xml version ='1.0'?>"
|
||||
"<!-- Top level comment. -->"
|
||||
"<root>"
|
||||
" <child1 foo='bar'/>"
|
||||
" <!-- comment thing -->"
|
||||
" <child2 val='1'>Text</child2>"
|
||||
"</root>";
|
||||
XMLDocument doc;
|
||||
doc.Parse(xml);
|
||||
doc.Print(&printer1);
|
||||
|
||||
doc.DeepCopy(&doc2);
|
||||
}
|
||||
XMLPrinter printer2;
|
||||
doc2.Print(&printer2);
|
||||
|
||||
XMLTest("DeepCopy of document.", printer1.CStr(), printer2.CStr(), true);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
// This shouldn't crash.
|
||||
XMLDocument doc;
|
||||
|
|
Loading…
Reference in New Issue