diff --git a/tinyxml2.cpp b/tinyxml2.cpp index 0a02c4b..9df038f 100644 --- a/tinyxml2.cpp +++ b/tinyxml2.cpp @@ -186,6 +186,7 @@ char* XMLBase::Identify( XMLDocument* document, char* p, XMLNode** node ) XMLNode::XMLNode( XMLDocument* doc ) : document( doc ), parent( 0 ), + isTextParent( false ), firstChild( 0 ), lastChild( 0 ), prev( 0 ), next( 0 ) { @@ -242,6 +243,9 @@ XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) addThis->prev = 0; addThis->next = 0; } + if ( addThis->ToText() ) { + SetTextParent(); + } return addThis; } @@ -254,6 +258,25 @@ void XMLNode::Print( FILE* fp, int depth ) } +char* XMLNode::ParseDeep( char* p ) +{ + while( p && *p ) { + XMLNode* node = 0; + p = Identify( document, p, &node ); + if ( p && node ) { + p = node->ParseDeep( p ); + // FIXME: is it the correct closing element? + if ( node->IsClosingElement() ) { + delete node; + return p; + } + this->InsertEndChild( node ); + } + } + return 0; +} + + void XMLNode::PrintSpace( FILE* fp, int depth ) { for( int i=0; i form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - closing = true; - ++p; - } - - p = ParseName( p, &name ); - if ( name.Empty() ) return 0; + *closedElement = false; // Read the attributes. while( p ) { @@ -400,6 +411,7 @@ char* XMLElement::ParseDeep( char* p ) document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p ); return 0; } + *closedElement = true; return p+2; // done; sealed element. } // end of the tag @@ -412,38 +424,47 @@ char* XMLElement::ParseDeep( char* p ) return 0; } } + return p; +} - while( p && *p ) { - XMLNode* node = 0; - p = Identify( document, p, &node ); - if ( p && node ) { - p = node->ParseDeep( p ); - XMLElement* element = node->ToElement(); - if ( element && element->Closing() ) { - if ( StringEqual( element->Name(), this->Name() ) ) { - // All good, this is closing tag. - delete node; - } - else { - document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p ); - delete node; - p = 0; - } - return p; - } - else { - this->InsertEndChild( node ); - } - } +// +// +// foobar +// +char* XMLElement::ParseDeep( char* p ) +{ + // Read the element name. + p = SkipWhiteSpace( p ); + if ( !p ) return 0; + const char* start = p; + + // The closing element is the form. It is + // parsed just like a regular element then deleted from + // the DOM. + if ( *p == '/' ) { + closing = true; + ++p; } - return 0; + + p = ParseName( p, &name ); + if ( name.Empty() ) return 0; + + bool elementClosed=false; + p = ParseAttributes( p, &elementClosed ); + if ( !p || !*p || elementClosed || closing ) + return p; + + p = XMLNode::ParseDeep( p ); + return p; } void XMLElement::Print( FILE* cfile, int depth ) { - PrintSpace( cfile, depth ); + if ( !parent || !parent->IsTextParent() ) { + PrintSpace( cfile, depth ); + } fprintf( cfile, "<%s", Name() ); for( XMLAttribute* attrib=rootAttribute; attrib; attrib=attrib->next ) { @@ -452,38 +473,39 @@ void XMLElement::Print( FILE* cfile, int depth ) } if ( firstChild ) { - // fixme: once text is on, it should stay on, and not use newlines. - bool useNewline = firstChild->ToText() == 0; - fprintf( cfile, ">", Name() ); - if ( useNewline ) fprintf( cfile, "\n" ); + if ( !IsTextParent() ) { + fprintf( cfile, "\n" ); + } for( XMLNode* node=firstChild; node; node=node->next ) { node->Print( cfile, depth+1 ); } - fprintf( cfile, "\n", Name() ); - // fixme: see note above - //if ( useNewline ) fprintf( cfile, "\n" ); + fprintf( cfile, "", Name() ); + if ( !IsTextParent() ) { + fprintf( cfile, "\n" ); + } } else { - fprintf( cfile, "/>\n" ); + fprintf( cfile, "/>" ); + if ( !IsTextParent() ) { + fprintf( cfile, "\n" ); + } } } // --------- XMLDocument ----------- // -XMLDocument::XMLDocument() : +XMLDocument::XMLDocument() : + XMLNode( this ), charBuffer( 0 ) { - root = new XMLNode( this ); } XMLDocument::~XMLDocument() { - delete root; - delete charBuffer; } @@ -493,25 +515,21 @@ bool XMLDocument::Parse( const char* p ) charBuffer = CharBuffer::Construct( p ); XMLNode* node = 0; - // fixme: clean up - char* q = Identify( this, charBuffer->mem, &node ); - while ( node ) { - root->InsertEndChild( node ); - q = node->ParseDeep( q ); - node = 0; - if ( q && *q ) { - q = Identify( this, q, &node ); - } - } - return false; + char* q = ParseDeep( charBuffer->mem ); + return true; } void XMLDocument::Print( FILE* fp, int depth ) { - for( XMLNode* node = root->firstChild; node; node=node->next ) { + for( XMLNode* node = firstChild; node; node=node->next ) { node->Print( fp, depth ); } } +void XMLDocument::SetError( int error, const char* str1, const char* str2 ) +{ + printf( "ERROR: id=%d '%s' '%s'\n", error, str1, str2 ); +} + diff --git a/tinyxml2.h b/tinyxml2.h index 227c7c7..4fbd33c 100644 --- a/tinyxml2.h +++ b/tinyxml2.h @@ -106,7 +106,6 @@ protected: char* Identify( XMLDocument* document, char* p, XMLNode** node ); }; - class XMLNode : public XMLBase { friend class XMLDocument; @@ -121,7 +120,12 @@ public: virtual XMLText* ToText() { return 0; } virtual XMLComment* ToComment() { return 0; } - virtual char* ParseDeep( char* ) { TIXMLASSERT( 0 ); } + // fixme: guarentee null terminator to avoid internal checks + virtual char* ParseDeep( char* ); + + void SetTextParent() { isTextParent = true; } + bool IsTextParent() const { return isTextParent; } + virtual bool IsClosingElement() const { return false; } protected: XMLNode( XMLDocument* ); @@ -129,6 +133,7 @@ protected: XMLDocument* document; XMLNode* parent; + bool isTextParent; XMLNode* firstChild; XMLNode* lastChild; @@ -208,13 +213,15 @@ public: virtual void Print( FILE* cfile, int depth ); virtual XMLElement* ToElement() { return this; } - bool Closing() const { return closing; } + virtual bool IsClosingElement() const { return closing; } char* ParseDeep( char* p ); protected: private: + char* ParseAttributes( char* p, bool *closedElement ); + StrPair name; bool closing; XMLAttribute* rootAttribute; @@ -222,7 +229,7 @@ private: }; -class XMLDocument : public XMLBase +class XMLDocument : public XMLNode { public: XMLDocument(); @@ -231,20 +238,19 @@ public: bool Parse( const char* ); void Print( FILE* cfile=stdout, int depth=0 ); + /* XMLNode* Root() { return root; } XMLNode* RootElement(); - + */ enum { ERROR_ELEMENT_MISMATCH, ERROR_PARSING_ELEMENT, ERROR_PARSING_ATTRIBUTE }; - void SetError( int error, const char* str1, const char* str2 ) {} + void SetError( int error, const char* str1, const char* str2 ); private: XMLDocument( const XMLDocument& ); // intentionally not implemented - - XMLNode* root; CharBuffer* charBuffer; }; diff --git a/tinyxml2.suo b/tinyxml2.suo deleted file mode 100644 index e3bbf90..0000000 Binary files a/tinyxml2.suo and /dev/null differ diff --git a/xmltest.cpp b/xmltest.cpp index 0301c41..6090a79 100644 --- a/xmltest.cpp +++ b/xmltest.cpp @@ -39,6 +39,8 @@ int main( int argc, const char* argv ) "", "", "Text inside element.", + "", + "Text inside and bolded in the element.", 0 }; for( int i=0; test[i]; ++i ) {