| 1372 | |
| 1373 | |
| 1374 | char* XMLElement::ParseAttributes( char* p ) { |
| 1375 | const char* start = p; |
| 1376 | XMLAttribute* prevAttribute = 0; |
| 1377 | |
| 1378 | // Read the attributes. |
| 1379 | while( p ) { |
| 1380 | p = XMLUtil::SkipWhiteSpace( p ); |
| 1381 | if ( !(*p) ) { |
| 1382 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); |
| 1383 | return 0; |
| 1384 | } |
| 1385 | |
| 1386 | // attribute. |
| 1387 | if (XMLUtil::IsNameStartChar( *p ) ) { |
| 1388 | TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); |
| 1389 | XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); |
| 1390 | attrib->_memPool = &_document->_attributePool; |
| 1391 | attrib->_memPool->SetTracked(); |
| 1392 | |
| 1393 | p = attrib->ParseDeep( p, _document->ProcessEntities() ); |
| 1394 | if ( !p || Attribute( attrib->Name() ) ) { |
| 1395 | DeleteAttribute( attrib ); |
| 1396 | _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); |
| 1397 | return 0; |
| 1398 | } |
| 1399 | // There is a minor bug here: if the attribute in the source xml |
| 1400 | // document is duplicated, it will not be detected and the |
| 1401 | // attribute will be doubly added. However, tracking the 'prevAttribute' |
| 1402 | // avoids re-scanning the attribute list. Preferring performance for |
| 1403 | // now, may reconsider in the future. |
| 1404 | if ( prevAttribute ) { |
| 1405 | prevAttribute->_next = attrib; |
| 1406 | } else { |
| 1407 | _rootAttribute = attrib; |
| 1408 | } |
| 1409 | prevAttribute = attrib; |
| 1410 | } |
| 1411 | // end of the tag |
| 1412 | else if ( *p == '/' && *(p+1) == '>' ) { |
| 1413 | _closingType = CLOSED; |
| 1414 | return p+2; // done; sealed element. |
| 1415 | } |
| 1416 | // end of the tag |
| 1417 | else if ( *p == '>' ) { |
| 1418 | ++p; |
| 1419 | break; |
| 1420 | } else { |
| 1421 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); |
| 1422 | return 0; |
| 1423 | } |
| 1424 | } |
| 1425 | return p; |
| 1426 | } |
| 1427 | |
| 1428 | void XMLElement::DeleteAttribute( XMLAttribute* attribute ) { |
| 1429 | if ( attribute == 0 ) { |