From d5c9e8b81d61fedd7b10e0e2627a06873022b9f6 Mon Sep 17 00:00:00 2001 From: Uli Kusterer Date: Sat, 1 Feb 2014 12:48:51 +0100 Subject: [PATCH 1/3] Added SetForceCompactMode() for overriding the compact setting on a per-node level. All sub-nodes will be printed compact as well. --- tinyxml2.cpp | 11 ++++++----- tinyxml2.h | 9 +++++++-- xmltest.cpp | 21 +++++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index cb26e00..91f4011 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -580,7 +580,8 @@ XMLNode::XMLNode( XMLDocument* doc ) : _parent( 0 ), _firstChild( 0 ), _lastChild( 0 ), _prev( 0 ), _next( 0 ), - _memPool( 0 ) + _memPool( 0 ), + _forceCompactMode( false ) { } @@ -1945,17 +1946,17 @@ void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) } -void XMLPrinter::OpenElement( const char* name ) +void XMLPrinter::OpenElement( const char* name, bool compactMode ) { if ( _elementJustOpened ) { SealElement(); } _stack.Push( name ); - if ( _textDepth < 0 && !_firstElement && !_compactMode ) { + if ( _textDepth < 0 && !_firstElement && !compactMode ) { Print( "\n" ); } - if ( !_compactMode ) { + if ( !compactMode ) { PrintSpace( _depth ); } @@ -2151,7 +2152,7 @@ bool XMLPrinter::VisitEnter( const XMLDocument& doc ) bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) { - OpenElement( element.Name() ); + OpenElement( element.Name(), _compactMode ? true : element.Parent()->GetForceCompactMode() ); while ( attribute ) { PushAttribute( attribute->Name(), attribute->Value() ); attribute = attribute->Next(); diff --git a/tinyxml2.h b/tinyxml2.h index 41f1c70..09f6dd2 100755 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -821,6 +821,9 @@ public: // internal virtual char* ParseDeep( char*, StrPair* ); + + bool GetForceCompactMode() const { if( _forceCompactMode || !Parent() ) return _forceCompactMode; return Parent()->GetForceCompactMode(); }; + void SetForceCompactMode( bool b ) { _forceCompactMode = b; }; protected: XMLNode( XMLDocument* ); @@ -837,6 +840,8 @@ protected: XMLNode* _prev; XMLNode* _next; + + bool _forceCompactMode; private: MemPool* _memPool; @@ -1463,7 +1468,7 @@ public: char* ParseDeep( char* p, StrPair* endTag ); virtual XMLNode* ShallowClone( XMLDocument* document ) const; virtual bool ShallowEqual( const XMLNode* compare ) const; - + private: XMLElement( XMLDocument* doc ); virtual ~XMLElement(); @@ -1961,7 +1966,7 @@ public: /** If streaming, start writing an element. The element must be closed with CloseElement() */ - void OpenElement( const char* name ); + void OpenElement( const char* name, bool compactMode ); /// If streaming, add an attribute to an open element. void PushAttribute( const char* name, const char* value ); void PushAttribute( const char* name, int value ); diff --git a/xmltest.cpp b/xmltest.cpp index 6fdc162..fa9e1a4 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -1012,6 +1012,27 @@ int main( int argc, const char ** argv ) ele->DeleteAttribute( "attrib3" ); XMLTest( "Attribute order (empty)", false, ele->FirstAttribute() ? true : false ); } + + { + XMLDocument doc0; + XMLElement* root = doc0.NewElement("root"); + doc0.InsertEndChild(root); + XMLElement* text = doc0.NewElement("text"); + text->SetForceCompactMode(true); + root->InsertEndChild(text); + XMLText* befText = doc0.NewText("Before "); + text->InsertEndChild(befText); + XMLElement* tag = doc0.NewElement("tag"); + text->InsertEndChild(tag); + XMLText* tagText = doc0.NewText("Tag"); + tag->InsertEndChild(tagText); + XMLText* aftText = doc0.NewText(" After"); + text->InsertEndChild(aftText); + + XMLPrinter printer; + doc0.Print( &printer ); + XMLTest( "Selective text wrapping", "\n Before Tag After\n\n", printer.CStr() ); + } { // Make sure an attribute with a space in it succeeds. From 15354f88c39e33174f9058130d9897f8a031b7bc Mon Sep 17 00:00:00 2001 From: Uli Kusterer Date: Sat, 1 Feb 2014 13:06:39 +0100 Subject: [PATCH 2/3] Give tests a few more chances to fail, e.g. on tag sequences or attributes. --- xmltest.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/xmltest.cpp b/xmltest.cpp index fa9e1a4..3997b64 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -1026,12 +1026,17 @@ int main( int argc, const char ** argv ) text->InsertEndChild(tag); XMLText* tagText = doc0.NewText("Tag"); tag->InsertEndChild(tagText); + tag = doc0.NewElement("tagtwo"); + tag->SetAttribute("two", "2"); + text->InsertEndChild(tag); + tagText = doc0.NewText("TagTwo"); + tag->InsertEndChild(tagText); XMLText* aftText = doc0.NewText(" After"); text->InsertEndChild(aftText); XMLPrinter printer; doc0.Print( &printer ); - XMLTest( "Selective text wrapping", "\n Before Tag After\n\n", printer.CStr() ); + XMLTest( "Selective text wrapping", "\n Before TagTagTwo After\n\n", printer.CStr() ); } { From ca412e87f2815dfbbf09ea056ed2515d6cb2ae12 Mon Sep 17 00:00:00 2001 From: Uli Kusterer Date: Sat, 1 Feb 2014 13:35:05 +0100 Subject: [PATCH 3/3] SetForceCompactMode() now also handles case of a single tag inside another correctly. --- tinyxml2.cpp | 10 +++++----- tinyxml2.h | 2 +- xmltest.cpp | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 91f4011..59a149e 100755 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -2008,7 +2008,7 @@ void XMLPrinter::PushAttribute( const char* name, double v ) } -void XMLPrinter::CloseElement() +void XMLPrinter::CloseElement( bool compactMode ) { --_depth; const char* name = _stack.Pop(); @@ -2017,7 +2017,7 @@ void XMLPrinter::CloseElement() Print( "/>" ); } else { - if ( _textDepth < 0 && !_compactMode) { + if ( _textDepth < 0 && !compactMode) { Print( "\n" ); PrintSpace( _depth ); } @@ -2027,7 +2027,7 @@ void XMLPrinter::CloseElement() if ( _textDepth == _depth ) { _textDepth = -1; } - if ( _depth == 0 && !_compactMode) { + if ( _depth == 0 && !compactMode) { Print( "\n" ); } _elementJustOpened = false; @@ -2161,9 +2161,9 @@ bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attr } -bool XMLPrinter::VisitExit( const XMLElement& ) +bool XMLPrinter::VisitExit( const XMLElement& element ) { - CloseElement(); + CloseElement( _compactMode ? true : element.GetForceCompactMode() ); return true; } diff --git a/tinyxml2.h b/tinyxml2.h index 09f6dd2..eae8cd4 100755 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -1974,7 +1974,7 @@ public: void PushAttribute( const char* name, bool value ); void PushAttribute( const char* name, double value ); /// If streaming, close the Element. - virtual void CloseElement(); + virtual void CloseElement( bool compactMode ); /// Add a text node. void PushText( const char* text, bool cdata=false ); diff --git a/xmltest.cpp b/xmltest.cpp index 3997b64..7c24090 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -1039,6 +1039,21 @@ int main( int argc, const char ** argv ) XMLTest( "Selective text wrapping", "\n Before TagTagTwo After\n\n", printer.CStr() ); } + { + XMLDocument doc0; + XMLElement* root = doc0.NewElement("root"); + doc0.InsertEndChild(root); + XMLElement* cool = doc0.NewElement("cool"); + cool->SetForceCompactMode(true); + root->InsertEndChild(cool); + XMLElement* tag = doc0.NewElement("true"); + cool->InsertEndChild(tag); + + XMLPrinter printer; + doc0.Print( &printer ); + XMLTest( "Selective text around single tag", "\n \n\n", printer.CStr() ); + } + { // Make sure an attribute with a space in it succeeds. static const char* xml0 = "";