mirror of https://github.com/AxioDL/tinyxml2.git
Insert() methods check for inserted XML to be in the same doc, and remove XML from old location if already inserted.
This commit is contained in:
parent
ab42b16bac
commit
ed52328ced
25
tinyxml2.cpp
25
tinyxml2.cpp
|
@ -625,7 +625,6 @@ void XMLNode::DeleteChildren()
|
|||
|
||||
void XMLNode::Unlink( XMLNode* child )
|
||||
{
|
||||
TIXMLASSERT( child->_parent == this );
|
||||
if ( child == _firstChild ) {
|
||||
_firstChild = _firstChild->_next;
|
||||
}
|
||||
|
@ -639,7 +638,6 @@ void XMLNode::Unlink( XMLNode* child )
|
|||
if ( child->_next ) {
|
||||
child->_next->_prev = child->_prev;
|
||||
}
|
||||
child->_parent = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -652,6 +650,12 @@ void XMLNode::DeleteChild( XMLNode* node )
|
|||
|
||||
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
if (addThis->_parent)
|
||||
addThis->_parent->Unlink( addThis );
|
||||
else
|
||||
addThis->_memPool->SetTracked();
|
||||
if ( _lastChild ) {
|
||||
TIXMLASSERT( _firstChild );
|
||||
TIXMLASSERT( _lastChild->_next == 0 );
|
||||
|
@ -669,13 +673,18 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
|||
addThis->_next = 0;
|
||||
}
|
||||
addThis->_parent = this;
|
||||
addThis->_memPool->SetTracked();
|
||||
return addThis;
|
||||
}
|
||||
|
||||
|
||||
XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
if (addThis->_parent)
|
||||
addThis->_parent->Unlink( addThis );
|
||||
else
|
||||
addThis->_memPool->SetTracked();
|
||||
if ( _firstChild ) {
|
||||
TIXMLASSERT( _lastChild );
|
||||
TIXMLASSERT( _firstChild->_prev == 0 );
|
||||
|
@ -694,13 +703,14 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
|||
addThis->_next = 0;
|
||||
}
|
||||
addThis->_parent = this;
|
||||
addThis->_memPool->SetTracked();
|
||||
return addThis;
|
||||
return addThis;
|
||||
}
|
||||
|
||||
|
||||
XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
||||
{
|
||||
if (addThis->_document != _document)
|
||||
return 0;
|
||||
TIXMLASSERT( afterThis->_parent == this );
|
||||
if ( afterThis->_parent != this ) {
|
||||
return 0;
|
||||
|
@ -710,12 +720,15 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
|||
// The last node or the only node.
|
||||
return InsertEndChild( addThis );
|
||||
}
|
||||
if (addThis->_parent)
|
||||
addThis->_parent->Unlink( addThis );
|
||||
else
|
||||
addThis->_memPool->SetTracked();
|
||||
addThis->_prev = afterThis;
|
||||
addThis->_next = afterThis->_next;
|
||||
afterThis->_next->_prev = addThis;
|
||||
afterThis->_next = addThis;
|
||||
addThis->_parent = this;
|
||||
addThis->_memPool->SetTracked();
|
||||
return addThis;
|
||||
}
|
||||
|
||||
|
|
13
tinyxml2.h
13
tinyxml2.h
|
@ -734,6 +734,10 @@ public:
|
|||
|
||||
/**
|
||||
Add a child node as the last (right) child.
|
||||
If the child node is already part of the document,
|
||||
it is moved from its old location to the new location.
|
||||
Returns the addThis argument or 0 if the node does not
|
||||
belong to the same document.
|
||||
*/
|
||||
XMLNode* InsertEndChild( XMLNode* addThis );
|
||||
|
||||
|
@ -742,10 +746,19 @@ public:
|
|||
}
|
||||
/**
|
||||
Add a child node as the first (left) child.
|
||||
If the child node is already part of the document,
|
||||
it is moved from its old location to the new location.
|
||||
Returns the addThis argument or 0 if the node does not
|
||||
belong to the same document.
|
||||
*/
|
||||
XMLNode* InsertFirstChild( XMLNode* addThis );
|
||||
/**
|
||||
Add a node after the specified child node.
|
||||
If the child node is already part of the document,
|
||||
it is moved from its old location to the new location.
|
||||
Returns the addThis argument or 0 if the afterThis node
|
||||
is not a child of this node, or if the node does not
|
||||
belong to the same document.
|
||||
*/
|
||||
XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
|
||||
|
||||
|
|
71
xmltest.cpp
71
xmltest.cpp
|
@ -1202,6 +1202,77 @@ int main( int argc, const char ** argv )
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Insertion with Removal
|
||||
const char* xml = "<?xml version=\"1.0\" ?>"
|
||||
"<root>"
|
||||
"<one>"
|
||||
"<subtree>"
|
||||
"<elem>element 1</elem>text<!-- comment -->"
|
||||
"</subtree>"
|
||||
"</one>"
|
||||
"<two/>"
|
||||
"</root>";
|
||||
const char* xmlInsideTwo = "<?xml version=\"1.0\" ?>"
|
||||
"<root>"
|
||||
"<one/>"
|
||||
"<two>"
|
||||
"<subtree>"
|
||||
"<elem>element 1</elem>text<!-- comment -->"
|
||||
"</subtree>"
|
||||
"</two>"
|
||||
"</root>";
|
||||
const char* xmlAfterOne = "<?xml version=\"1.0\" ?>"
|
||||
"<root>"
|
||||
"<one/>"
|
||||
"<subtree>"
|
||||
"<elem>element 1</elem>text<!-- comment -->"
|
||||
"</subtree>"
|
||||
"<two/>"
|
||||
"</root>";
|
||||
const char* xmlAfterTwo = "<?xml version=\"1.0\" ?>"
|
||||
"<root>"
|
||||
"<one/>"
|
||||
"<two/>"
|
||||
"<subtree>"
|
||||
"<elem>element 1</elem>text<!-- comment -->"
|
||||
"</subtree>"
|
||||
"</root>";
|
||||
|
||||
XMLDocument doc;
|
||||
doc.Parse( xml );
|
||||
XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
|
||||
XMLElement* two = doc.RootElement()->FirstChildElement("two");
|
||||
two->InsertFirstChild(subtree);
|
||||
XMLPrinter printer1( 0, true );
|
||||
doc.Accept( &printer1 );
|
||||
XMLTest( "Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr());
|
||||
|
||||
doc.Parse( xml );
|
||||
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
|
||||
two = doc.RootElement()->FirstChildElement("two");
|
||||
doc.RootElement()->InsertAfterChild(two, subtree);
|
||||
XMLPrinter printer2( 0, true );
|
||||
doc.Accept( &printer2 );
|
||||
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr());
|
||||
|
||||
doc.Parse( xml );
|
||||
XMLNode* one = doc.RootElement()->FirstChildElement("one");
|
||||
subtree = one->FirstChildElement("subtree");
|
||||
doc.RootElement()->InsertAfterChild(one, subtree);
|
||||
XMLPrinter printer3( 0, true );
|
||||
doc.Accept( &printer3 );
|
||||
XMLTest( "Move node from within <one> after <one>", xmlAfterOne, printer3.CStr());
|
||||
|
||||
doc.Parse( xml );
|
||||
subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree");
|
||||
two = doc.RootElement()->FirstChildElement("two");
|
||||
doc.RootElement()->InsertEndChild(subtree);
|
||||
XMLPrinter printer4( 0, true );
|
||||
doc.Accept( &printer4 );
|
||||
XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr());
|
||||
}
|
||||
|
||||
// ----------- Performance tracking --------------
|
||||
{
|
||||
#if defined( _MSC_VER )
|
||||
|
|
Loading…
Reference in New Issue