mirror of https://github.com/AxioDL/tinyxml2.git
better end element parsing
This commit is contained in:
parent
46a14cfec7
commit
7468f11413
74
tinyxml2.cpp
74
tinyxml2.cpp
|
@ -358,7 +358,7 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
|||
p = XMLUtil::SkipWhiteSpace( p );
|
||||
if( !p || !*p )
|
||||
{
|
||||
return 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
// What is this thing?
|
||||
|
@ -409,11 +409,6 @@ char* XMLDocument::Identify( char* p, XMLNode** node )
|
|||
returnNode = new (elementPool.Alloc()) XMLElement( this );
|
||||
returnNode->memPool = &elementPool;
|
||||
p += elementHeaderLen;
|
||||
|
||||
p = XMLUtil::SkipWhiteSpace( p );
|
||||
if ( p && *p == '/' ) {
|
||||
((XMLElement*)returnNode)->closingType = XMLElement::CLOSING;
|
||||
}
|
||||
}
|
||||
else {
|
||||
returnNode = new (textPool.Alloc()) XMLText( this );
|
||||
|
@ -602,7 +597,7 @@ const XMLElement* XMLNode::LastChildElement( const char* value ) const
|
|||
}
|
||||
|
||||
|
||||
char* XMLNode::ParseDeep( char* p )
|
||||
char* XMLNode::ParseDeep( char* p, StrPair* parentEnd )
|
||||
{
|
||||
// This is a recursive method, but thinking about it "at the current level"
|
||||
// it is a pretty simple flat list:
|
||||
|
@ -617,69 +612,67 @@ char* XMLNode::ParseDeep( char* p )
|
|||
// Where the closing element (/foo) *must* be the next thing after the opening
|
||||
// element, and the names must match. BUT the tricky bit is that the closing
|
||||
// element will be read by the child.
|
||||
//
|
||||
// 'endTag' is the end tag for this node, it is returned by a call to a child.
|
||||
// 'parentEnd' is the end tag for the parent, which is filled in and returned.
|
||||
|
||||
while( p && *p ) {
|
||||
XMLNode* node = 0;
|
||||
char* mark = p;
|
||||
|
||||
p = document->Identify( p, &node );
|
||||
if ( p == 0 ) {
|
||||
if ( p == 0 || node == 0 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// We read the end tag. Back up and return.
|
||||
if ( node && node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) {
|
||||
DELETE_NODE( node );
|
||||
return mark;
|
||||
}
|
||||
|
||||
if ( node ) {
|
||||
p = node->ParseDeep( p );
|
||||
StrPair endTag;
|
||||
p = node->ParseDeep( p, &endTag );
|
||||
if ( !p ) {
|
||||
DELETE_NODE( node );
|
||||
node = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
XMLElement* ele = node->ToElement();
|
||||
if ( ele && ele->ClosingType() == XMLElement::OPEN ) {
|
||||
XMLNode* closingNode = 0;
|
||||
p = document->Identify( p, &closingNode );
|
||||
XMLElement* closingEle = closingNode ? closingNode->ToElement() : 0;
|
||||
// We read the end tag. Return it to the parent.
|
||||
if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) {
|
||||
if ( parentEnd ) {
|
||||
*parentEnd = ((XMLElement*)node)->value;
|
||||
}
|
||||
DELETE_NODE( node );
|
||||
return p;
|
||||
}
|
||||
|
||||
if ( closingEle == 0 ) {
|
||||
// Handle an end tag returned to this level.
|
||||
// And handle a bunch of annoying errors.
|
||||
XMLElement* ele = node->ToElement();
|
||||
if ( ele ) {
|
||||
if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) {
|
||||
document->SetError( ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
}
|
||||
else if ( closingEle->ClosingType() != XMLElement::CLOSING ) {
|
||||
else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) {
|
||||
document->SetError( ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = closingEle->ParseDeep( p );
|
||||
if ( !XMLUtil::StringEqual( closingEle->Value(), node->Value() )) {
|
||||
else if ( !endTag.Empty() ) {
|
||||
if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) {
|
||||
document->SetError( ERROR_MISMATCHED_ELEMENT, node->Value(), 0 );
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
// Else everything is fine, but we need to throw away the node.
|
||||
DELETE_NODE( closingNode );
|
||||
}
|
||||
if ( p == 0 ) {
|
||||
DELETE_NODE( node );
|
||||
node = 0;
|
||||
}
|
||||
}
|
||||
if ( node ) {
|
||||
this->InsertEndChild( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// --------- XMLText ---------- //
|
||||
char* XMLText::ParseDeep( char* p )
|
||||
char* XMLText::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
const char* start = p;
|
||||
if ( this->CData() ) {
|
||||
|
@ -721,7 +714,7 @@ XMLComment::~XMLComment()
|
|||
}
|
||||
|
||||
|
||||
char* XMLComment::ParseDeep( char* p )
|
||||
char* XMLComment::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
// Comment parses as text.
|
||||
const char* start = p;
|
||||
|
@ -752,7 +745,7 @@ XMLDeclaration::~XMLDeclaration()
|
|||
}
|
||||
|
||||
|
||||
char* XMLDeclaration::ParseDeep( char* p )
|
||||
char* XMLDeclaration::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
// Declaration parses as text.
|
||||
const char* start = p;
|
||||
|
@ -781,7 +774,7 @@ XMLUnknown::~XMLUnknown()
|
|||
}
|
||||
|
||||
|
||||
char* XMLUnknown::ParseDeep( char* p )
|
||||
char* XMLUnknown::ParseDeep( char* p, StrPair* )
|
||||
{
|
||||
// Unknown parses as text.
|
||||
const char* start = p;
|
||||
|
@ -1056,7 +1049,7 @@ char* XMLElement::ParseAttributes( char* p )
|
|||
// <ele></ele>
|
||||
// <ele>foo<b>bar</b></ele>
|
||||
//
|
||||
char* XMLElement::ParseDeep( char* p )
|
||||
char* XMLElement::ParseDeep( char* p, StrPair* strPair )
|
||||
{
|
||||
// Read the element name.
|
||||
p = XMLUtil::SkipWhiteSpace( p );
|
||||
|
@ -1079,7 +1072,8 @@ char* XMLElement::ParseDeep( char* p )
|
|||
if ( !p || !*p || closingType )
|
||||
return p;
|
||||
|
||||
p = XMLNode::ParseDeep( p );
|
||||
p = XMLNode::ParseDeep( p, strPair );
|
||||
// FIXME: proces end tage here??
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -1207,7 +1201,7 @@ int XMLDocument::LoadFile( FILE* fp )
|
|||
return errorID;
|
||||
}
|
||||
|
||||
ParseDeep( charBuffer + (p-charBuffer) );
|
||||
ParseDeep( charBuffer + (p-charBuffer), 0 );
|
||||
return errorID;
|
||||
}
|
||||
|
||||
|
@ -1242,7 +1236,7 @@ int XMLDocument::Parse( const char* p )
|
|||
memcpy( charBuffer, p, len+1 );
|
||||
|
||||
|
||||
ParseDeep( charBuffer );
|
||||
ParseDeep( charBuffer, 0 );
|
||||
return errorID;
|
||||
}
|
||||
|
||||
|
|
12
tinyxml2.h
12
tinyxml2.h
|
@ -462,7 +462,7 @@ public:
|
|||
|
||||
virtual bool Accept( XMLVisitor* visitor ) const = 0;
|
||||
|
||||
virtual char* ParseDeep( char* );
|
||||
virtual char* ParseDeep( char*, StrPair* );
|
||||
|
||||
protected:
|
||||
XMLNode( XMLDocument* );
|
||||
|
@ -499,7 +499,7 @@ public:
|
|||
void SetCData( bool value ) { isCData = true; }
|
||||
bool CData() const { return isCData; }
|
||||
|
||||
char* ParseDeep( char* );
|
||||
char* ParseDeep( char*, StrPair* endTag );
|
||||
|
||||
protected:
|
||||
XMLText( XMLDocument* doc ) : XMLNode( doc ), isCData( false ) {}
|
||||
|
@ -521,7 +521,7 @@ public:
|
|||
|
||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||
|
||||
char* ParseDeep( char* );
|
||||
char* ParseDeep( char*, StrPair* endTag );
|
||||
|
||||
protected:
|
||||
XMLComment( XMLDocument* doc );
|
||||
|
@ -542,7 +542,7 @@ public:
|
|||
|
||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||
|
||||
char* ParseDeep( char* );
|
||||
char* ParseDeep( char*, StrPair* endTag );
|
||||
|
||||
protected:
|
||||
XMLDeclaration( XMLDocument* doc );
|
||||
|
@ -561,7 +561,7 @@ public:
|
|||
|
||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||
|
||||
char* ParseDeep( char* );
|
||||
char* ParseDeep( char*, StrPair* endTag );
|
||||
|
||||
protected:
|
||||
XMLUnknown( XMLDocument* doc );
|
||||
|
@ -686,7 +686,7 @@ public:
|
|||
CLOSING // </foo>
|
||||
};
|
||||
int ClosingType() const { return closingType; }
|
||||
char* ParseDeep( char* p );
|
||||
char* ParseDeep( char* p, StrPair* endTag );
|
||||
|
||||
private:
|
||||
XMLElement( XMLDocument* doc );
|
||||
|
|
Loading…
Reference in New Issue