Better attribute system. Removes redundant list searching of LinkAttribute. Faster parsing on initial read. Added badly needed missing test cases.
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index 4ce9b32..fbeca4e 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -1092,34 +1092,33 @@
 }

 

 

-

 XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )

 {

-	XMLAttribute* attrib = FindAttribute( name );

+	XMLAttribute* last = 0;

+	XMLAttribute* attrib = 0;

+	for( attrib = rootAttribute;

+		 attrib;

+		 last = attrib, attrib = attrib->next )

+	{		 

+		if ( XMLUtil::StringEqual( attrib->Name(), name ) ) {

+			break;

+		}

+	}

 	if ( !attrib ) {

 		attrib = new (document->attributePool.Alloc() ) XMLAttribute();

 		attrib->memPool = &document->attributePool;

-		LinkAttribute( attrib );

+		if ( last ) {

+			last->next = attrib;

+		}

+		else {

+			rootAttribute = attrib;

+		}

 		attrib->SetName( name );

 	}

 	return attrib;

 }

 

 

-void XMLElement::LinkAttribute( XMLAttribute* attrib )

-{

-	if ( rootAttribute ) {

-		XMLAttribute* end = rootAttribute;

-		while ( end->next )

-			end = end->next;

-		end->next = attrib;

-	}

-	else {

-		rootAttribute = attrib;

-	}

-}

-

-

 void XMLElement::DeleteAttribute( const char* name )

 {

 	XMLAttribute* prev = 0;

@@ -1142,6 +1141,7 @@
 char* XMLElement::ParseAttributes( char* p )

 {

 	const char* start = p;

+	XMLAttribute* prevAttribute = 0;

 

 	// Read the attributes.

 	while( p ) {

@@ -1162,7 +1162,19 @@
 				document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p );

 				return 0;

 			}

-			LinkAttribute( attrib );

+			// There is a minor bug here: if the attribute in the source xml

+			// document is duplicated, it will not be detected and the

+			// attribute will be doubly added. However, tracking the 'prevAttribute'

+			// avoids re-scanning the attribute list. Preferring performance for

+			// now, may reconsider in the future.

+			if ( prevAttribute ) { 

+				prevAttribute->next = attrib;

+				prevAttribute = attrib;

+			}

+			else {

+				rootAttribute = attrib;

+				prevAttribute = rootAttribute;

+			}	

 		}

 		// end of the tag

 		else if ( *p == '/' && *(p+1) == '>' ) {