char* XMLElement::ParseAttributes( char* p ) { const char* start = p; XMLAttribute* prevAttribute = 0; // Read the attributes. while( p ) { p = XMLUtil::SkipWhiteSpace( p ); if ( !p || !(*p) ) { _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); return 0; } // attribute. if (XMLUtil::IsNameStartChar( *p ) ) { XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); attrib->_memPool = &_document->_attributePool; attrib->_memPool->SetTracked(); p = attrib->ParseDeep( p, _document->ProcessEntities() ); if ( !p || Attribute( attrib->Name() ) ) { DELETE_ATTRIBUTE( attrib ); _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); return 0; } // 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; } else { _rootAttribute = attrib; } prevAttribute = attrib; } // end of the tag else if ( *p == '/' && *(p+1) == '>' ) { _closingType = CLOSED; return p+2; // done; sealed element. } // end of the tag else if ( *p == '>' ) { ++p; break; } else { _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); return 0; } } return p; }
char* XMLElement::ParseAttributes( char* p ) { const char* start = p; // Read the attributes. while( p ) { p = XMLUtil::SkipWhiteSpace( p ); if ( !p || !(*p) ) { document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); return 0; } // attribute. if ( XMLUtil::IsAlpha( *p ) ) { XMLAttribute* attrib = new (document->attributePool.Alloc() ) XMLAttribute(); attrib->memPool = &document->attributePool; p = attrib->ParseDeep( p, document->ProcessEntities() ); if ( !p || Attribute( attrib->Name() ) ) { DELETE_ATTRIBUTE( attrib ); document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); return 0; } LinkAttribute( attrib ); } // end of the tag else if ( *p == '/' && *(p+1) == '>' ) { closingType = CLOSED; return p+2; // done; sealed element. } // end of the tag else if ( *p == '>' ) { ++p; break; } else { document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); return 0; } } return p; }