mirror of
https://github.com/AxioDL/tinyxml2.git
synced 2025-06-18 12:33:33 +00:00
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 )
|
void XMLNode::Unlink( XMLNode* child )
|
||||||
{
|
{
|
||||||
TIXMLASSERT( child->_parent == this );
|
|
||||||
if ( child == _firstChild ) {
|
if ( child == _firstChild ) {
|
||||||
_firstChild = _firstChild->_next;
|
_firstChild = _firstChild->_next;
|
||||||
}
|
}
|
||||||
@ -639,7 +638,6 @@ void XMLNode::Unlink( XMLNode* child )
|
|||||||
if ( child->_next ) {
|
if ( child->_next ) {
|
||||||
child->_next->_prev = child->_prev;
|
child->_next->_prev = child->_prev;
|
||||||
}
|
}
|
||||||
child->_parent = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -652,6 +650,12 @@ void XMLNode::DeleteChild( XMLNode* node )
|
|||||||
|
|
||||||
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
||||||
{
|
{
|
||||||
|
if (addThis->_document != _document)
|
||||||
|
return 0;
|
||||||
|
if (addThis->_parent)
|
||||||
|
addThis->_parent->Unlink( addThis );
|
||||||
|
else
|
||||||
|
addThis->_memPool->SetTracked();
|
||||||
if ( _lastChild ) {
|
if ( _lastChild ) {
|
||||||
TIXMLASSERT( _firstChild );
|
TIXMLASSERT( _firstChild );
|
||||||
TIXMLASSERT( _lastChild->_next == 0 );
|
TIXMLASSERT( _lastChild->_next == 0 );
|
||||||
@ -669,13 +673,18 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
|
|||||||
addThis->_next = 0;
|
addThis->_next = 0;
|
||||||
}
|
}
|
||||||
addThis->_parent = this;
|
addThis->_parent = this;
|
||||||
addThis->_memPool->SetTracked();
|
|
||||||
return addThis;
|
return addThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLNode* XMLNode::InsertFirstChild( XMLNode* 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 ) {
|
if ( _firstChild ) {
|
||||||
TIXMLASSERT( _lastChild );
|
TIXMLASSERT( _lastChild );
|
||||||
TIXMLASSERT( _firstChild->_prev == 0 );
|
TIXMLASSERT( _firstChild->_prev == 0 );
|
||||||
@ -694,13 +703,14 @@ XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis )
|
|||||||
addThis->_next = 0;
|
addThis->_next = 0;
|
||||||
}
|
}
|
||||||
addThis->_parent = this;
|
addThis->_parent = this;
|
||||||
addThis->_memPool->SetTracked();
|
return addThis;
|
||||||
return addThis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
||||||
{
|
{
|
||||||
|
if (addThis->_document != _document)
|
||||||
|
return 0;
|
||||||
TIXMLASSERT( afterThis->_parent == this );
|
TIXMLASSERT( afterThis->_parent == this );
|
||||||
if ( afterThis->_parent != this ) {
|
if ( afterThis->_parent != this ) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -710,12 +720,15 @@ XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis )
|
|||||||
// The last node or the only node.
|
// The last node or the only node.
|
||||||
return InsertEndChild( addThis );
|
return InsertEndChild( addThis );
|
||||||
}
|
}
|
||||||
|
if (addThis->_parent)
|
||||||
|
addThis->_parent->Unlink( addThis );
|
||||||
|
else
|
||||||
|
addThis->_memPool->SetTracked();
|
||||||
addThis->_prev = afterThis;
|
addThis->_prev = afterThis;
|
||||||
addThis->_next = afterThis->_next;
|
addThis->_next = afterThis->_next;
|
||||||
afterThis->_next->_prev = addThis;
|
afterThis->_next->_prev = addThis;
|
||||||
afterThis->_next = addThis;
|
afterThis->_next = addThis;
|
||||||
addThis->_parent = this;
|
addThis->_parent = this;
|
||||||
addThis->_memPool->SetTracked();
|
|
||||||
return addThis;
|
return addThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
tinyxml2.h
13
tinyxml2.h
@ -734,6 +734,10 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Add a child node as the last (right) child.
|
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 );
|
XMLNode* InsertEndChild( XMLNode* addThis );
|
||||||
|
|
||||||
@ -742,10 +746,19 @@ public:
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
Add a child node as the first (left) child.
|
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 );
|
XMLNode* InsertFirstChild( XMLNode* addThis );
|
||||||
/**
|
/**
|
||||||
Add a node after the specified child node.
|
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 );
|
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 --------------
|
// ----------- Performance tracking --------------
|
||||||
{
|
{
|
||||||
#if defined( _MSC_VER )
|
#if defined( _MSC_VER )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user