| 1497 | |
| 1498 | |
| 1499 | char* XMLElement::ParseAttributes( char* p ) |
| 1500 | { |
| 1501 | const char* start = p; |
| 1502 | XMLAttribute* prevAttribute = 0; |
| 1503 | |
| 1504 | // Read the attributes. |
| 1505 | while( p ) { |
| 1506 | p = XMLUtil::SkipWhiteSpace( p ); |
| 1507 | if ( !(*p) ) { |
| 1508 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); |
| 1509 | return 0; |
| 1510 | } |
| 1511 | |
| 1512 | // attribute. |
| 1513 | if (XMLUtil::IsNameStartChar( *p ) ) { |
| 1514 | TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); |
| 1515 | XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); |
| 1516 | attrib->_memPool = &_document->_attributePool; |
| 1517 | attrib->_memPool->SetTracked(); |
| 1518 | |
| 1519 | p = attrib->ParseDeep( p, _document->ProcessEntities() ); |
| 1520 | if ( !p || Attribute( attrib->Name() ) ) { |
| 1521 | DeleteAttribute( attrib ); |
| 1522 | _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); |
| 1523 | return 0; |
| 1524 | } |
| 1525 | // There is a minor bug here: if the attribute in the source xml |
| 1526 | // document is duplicated, it will not be detected and the |
| 1527 | // attribute will be doubly added. However, tracking the 'prevAttribute' |
| 1528 | // avoids re-scanning the attribute list. Preferring performance for |
| 1529 | // now, may reconsider in the future. |
| 1530 | if ( prevAttribute ) { |
| 1531 | prevAttribute->_next = attrib; |
| 1532 | } |
| 1533 | else { |
| 1534 | _rootAttribute = attrib; |
| 1535 | } |
| 1536 | prevAttribute = attrib; |
| 1537 | } |
| 1538 | // end of the tag |
| 1539 | else if ( *p == '/' && *(p+1) == '>' ) { |
| 1540 | _closingType = CLOSED; |
| 1541 | return p+2; // done; sealed element. |
| 1542 | } |
| 1543 | // end of the tag |
| 1544 | else if ( *p == '>' ) { |
| 1545 | ++p; |
| 1546 | break; |
| 1547 | } |
| 1548 | else { |
| 1549 | _document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); |
| 1550 | return 0; |
| 1551 | } |
| 1552 | } |
| 1553 | return p; |
| 1554 | } |
| 1555 | |
| 1556 | void XMLElement::DeleteAttribute( XMLAttribute* attribute ) |