18#pragma warning(push, 0)
23#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
31#if defined(_MSC_VER) &&(_MSC_VER >= 1400 ) &&(!defined WINCE)
40static inline int TIXML_SNPRINTF(
char* buffer,
int size,
const char* format, ...)
43 va_start(va, format );
44 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, va );
49static inline int TIXML_VSNPRINTF(
char* buffer,
int size,
const char* format, va_list va )
51 int result = vsnprintf_s(buffer, size, _TRUNCATE, format, va );
55#define TIXML_VSCPRINTF _vscprintf
56#define TIXML_SSCANF sscanf_s
59#define TIXML_SNPRINTF _snprintf
60#define TIXML_VSNPRINTF _vsnprintf
61#define TIXML_SSCANF sscanf
62#if(_MSC_VER < 1400 ) &&(!defined WINCE)
64#define TIXML_VSCPRINTF _vscprintf
67static inline int TIXML_VSCPRINTF(
const char* format, va_list va )
73 char* str =
new char[len]();
74 const int required = _vsnprintf(str, len, format, va);
78 TIXMLASSERT(required >= 0 );
83 TIXMLASSERT(len >= 0 );
90#define TIXML_SNPRINTF snprintf
91#define TIXML_VSNPRINTF vsnprintf
92static inline int TIXML_VSCPRINTF(
const char* format, va_list va )
94 int len = vsnprintf(0, 0, format, va );
95 TIXMLASSERT(len >= 0 );
98#define TIXML_SSCANF sscanf
102static const char LINE_FEED = (char)0x0a;
103static const char LF = LINE_FEED;
104static const char CARRIAGE_RETURN = (char)0x0d;
105static const char CR = CARRIAGE_RETURN;
106static const char SINGLE_QUOTE =
'\'';
107static const char DOUBLE_QUOTE =
'\"';
113static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
114static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
115static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
127static const int NUM_ENTITIES = 5;
128static const Entity entities[NUM_ENTITIES] =
130 {
"quot", 4, DOUBLE_QUOTE },
132 {
"apos", 4, SINGLE_QUOTE },
144void StrPair::TransferTo(StrPair* other )
153 TIXMLASSERT(other != 0 );
154 TIXMLASSERT(other->_flags == 0 );
155 TIXMLASSERT(other->_start == 0 );
156 TIXMLASSERT(other->_end == 0 );
160 other->_flags = _flags;
161 other->_start = _start;
172 if(_flags & NEEDS_DELETE )
182void StrPair::SetStr(
const char* str,
int flags )
186 int len = strlen(str );
187 TIXMLASSERT(_start == 0 );
188 _start =
new char[ len+1 ];
189 memcpy(_start, str, len+1 );
191 _flags = flags | NEEDS_DELETE;
195char* StrPair::ParseText(
char* p,
const char* endTag,
int strFlags,
int* curLineNumPtr )
198 TIXMLASSERT(endTag && *endTag );
199 TIXMLASSERT(curLineNumPtr);
202 char endChar = *endTag;
203 int length = strlen(endTag );
208 if(*p == endChar && strncmp(p, endTag, length ) == 0 )
210 Set(start, p, strFlags );
224char* StrPair::ParseName(
char* p )
230 if(!XMLUtil::IsNameStartChar(*p ))
235 char*
const start = p;
237 while(*p && XMLUtil::IsNameChar(*p ))
247void StrPair::CollapseWhitespace()
250 TIXMLASSERT((_flags & NEEDS_DELETE ) == 0 );
252 _start = XMLUtil::SkipWhiteSpace(_start, 0 );
256 const char* p = _start;
261 if(XMLUtil::IsWhiteSpace(*p ))
263 p = XMLUtil::SkipWhiteSpace(p, 0 );
280const char* StrPair::GetStr()
282 TIXMLASSERT(_start );
284 if(_flags & NEEDS_FLUSH )
287 _flags ^= NEEDS_FLUSH;
291 const char* p = _start;
296 if((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR )
312 else if((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF )
325 else if((_flags & NEEDS_ENTITY_PROCESSING) && *p ==
'&')
334 const int buflen = 10;
335 char buf[buflen] = { 0 };
337 char* adjusted =
const_cast<char*
>(XMLUtil::GetCharacterRef(p, buf, &len ));
346 TIXMLASSERT(0 <= len && len <= buflen );
347 TIXMLASSERT(q + len <= adjusted );
349 memcpy(q, buf, len );
355 bool entityFound =
false;
356 for(
int i = 0; i < NUM_ENTITIES; ++i )
358 const Entity& entity = entities[i];
359 if(strncmp(p + 1, entity.pattern, entity.length ) == 0
360 && *(p + entity.length + 1 ) ==
';')
365 p += entity.length + 2;
389 if(_flags & NEEDS_WHITESPACE_COLLAPSING )
391 CollapseWhitespace();
393 _flags = (_flags & NEEDS_DELETE);
395 TIXMLASSERT(_start );
404const char* XMLUtil::writeBoolTrue =
"true";
405const char* XMLUtil::writeBoolFalse =
"false";
407void XMLUtil::SetBoolSerialization(
const char* writeTrue,
const char* writeFalse)
409 static const char* defTrue =
"true";
410 static const char* defFalse =
"false";
412 writeBoolTrue = (writeTrue) ? writeTrue : defTrue;
413 writeBoolFalse = (writeFalse) ? writeFalse : defFalse;
417const char* XMLUtil::ReadBOM(
const char* p,
bool* bom )
422 const unsigned char* pu =
reinterpret_cast<const unsigned char*
>(p);
424 if( *(pu+0) == TIXML_UTF_LEAD_0
425 && *(pu+1) == TIXML_UTF_LEAD_1
426 && *(pu+2) == TIXML_UTF_LEAD_2 )
436void XMLUtil::ConvertUTF32ToUTF8(
unsigned long input,
char* output,
int* length )
438 const unsigned long BYTE_MASK = 0xBF;
439 const unsigned long BYTE_MARK = 0x80;
440 const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
446 else if(input < 0x800 )
450 else if(input < 0x10000 )
454 else if(input < 0x200000 )
472 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
477 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
482 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
487 *output = (char)(input | FIRST_BYTE_MARK[*length]);
495const char* XMLUtil::GetCharacterRef(
const char* p,
char* value,
int* length )
500 if(*(p+1) ==
'#' && *(p+2))
502 unsigned long ucs = 0;
503 TIXMLASSERT(
sizeof(ucs ) >= 4 );
506 static const char SEMICOLON =
';';
517 q = strchr(q, SEMICOLON );
523 TIXMLASSERT(*q == SEMICOLON );
530 unsigned int digit = 0;
532 if(*q >=
'0' && *q <=
'9')
536 else if(*q >=
'a' && *q <=
'f')
538 digit = *q -
'a' + 10;
540 else if(*q >=
'A' && *q <=
'F')
542 digit = *q -
'A' + 10;
548 TIXMLASSERT(digit < 16 );
549 TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit );
550 const unsigned int digitScaled = mult * digit;
551 TIXMLASSERT(ucs <= ULONG_MAX - digitScaled );
553 TIXMLASSERT(mult <= UINT_MAX / 16 );
567 q = strchr(q, SEMICOLON );
573 TIXMLASSERT(*q == SEMICOLON );
580 if(*q >=
'0' && *q <=
'9')
582 const unsigned int digit = *q -
'0';
583 TIXMLASSERT(digit < 10 );
584 TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit );
585 const unsigned int digitScaled = mult * digit;
586 TIXMLASSERT(ucs <= ULONG_MAX - digitScaled );
593 TIXMLASSERT(mult <= UINT_MAX / 10 );
599 ConvertUTF32ToUTF8(ucs, value, length );
600 return p + delta + 1;
606void XMLUtil::ToStr(
int v,
char* buffer,
int bufferSize )
608 TIXML_SNPRINTF(buffer, bufferSize,
"%d", v );
612void XMLUtil::ToStr(
unsigned v,
char* buffer,
int bufferSize )
614 TIXML_SNPRINTF(buffer, bufferSize,
"%u", v );
618void XMLUtil::ToStr(
bool v,
char* buffer,
int bufferSize )
620 TIXML_SNPRINTF(buffer, bufferSize,
"%s", v ? writeBoolTrue : writeBoolFalse);
627void XMLUtil::ToStr(
float v,
char* buffer,
int bufferSize )
629 TIXML_SNPRINTF(buffer, bufferSize,
"%.8g", v );
633void XMLUtil::ToStr(
double v,
char* buffer,
int bufferSize )
635 TIXML_SNPRINTF(buffer, bufferSize,
"%.17g", v );
639void XMLUtil::ToStr(int64_t v,
char* buffer,
int bufferSize)
642 TIXML_SNPRINTF(buffer, bufferSize,
"%lld",(
long long)v);
646bool XMLUtil::ToInt(
const char* str,
int* value )
648 if(TIXML_SSCANF(str,
"%d", value ) == 1 )
655bool XMLUtil::ToUnsigned(
const char* str,
unsigned *value )
657 if(TIXML_SSCANF(str,
"%u", value ) == 1 )
664bool XMLUtil::ToBool(
const char* str,
bool* value )
667 if(ToInt(str, &ival ))
669 *value = (ival==0) ?
false :
true;
672 if(StringEqual(str,
"true"))
677 else if(StringEqual(str,
"false"))
686bool XMLUtil::ToFloat(
const char* str,
float* value )
688 if(TIXML_SSCANF(str,
"%f", value ) == 1 )
696bool XMLUtil::ToDouble(
const char* str,
double* value )
698 if(TIXML_SSCANF(str,
"%lf", value ) == 1 )
706bool XMLUtil::ToInt64(
const char* str, int64_t* value)
709 if(TIXML_SSCANF(str,
"%lld", &v) == 1)
718char* XMLDocument::Identify(
char* p, XMLNode** node )
722 char*
const start = p;
723 int const startLine = _parseCurLineNum;
724 p = XMLUtil::SkipWhiteSpace(p, &_parseCurLineNum );
733 static const char* xmlHeader = {
"<?" };
734 static const char* commentHeader = {
"<!--" };
735 static const char* cdataHeader = {
"<![CDATA[" };
736 static const char* dtdHeader = {
"<!" };
737 static const char* elementHeader = {
"<" };
739 static const int xmlHeaderLen = 2;
740 static const int commentHeaderLen = 4;
741 static const int cdataHeaderLen = 9;
742 static const int dtdHeaderLen = 2;
743 static const int elementHeaderLen = 1;
745 TIXMLASSERT(
sizeof(XMLComment ) ==
sizeof(XMLUnknown ));
746 TIXMLASSERT(
sizeof(XMLComment ) ==
sizeof(XMLDeclaration ));
747 XMLNode* returnNode = 0;
748 if(XMLUtil::StringEqual(p, xmlHeader, xmlHeaderLen ))
750 returnNode = CreateUnlinkedNode<XMLDeclaration>(_commentPool );
751 returnNode->_parseLineNum = _parseCurLineNum;
754 else if(XMLUtil::StringEqual(p, commentHeader, commentHeaderLen ))
756 returnNode = CreateUnlinkedNode<XMLComment>(_commentPool );
757 returnNode->_parseLineNum = _parseCurLineNum;
758 p += commentHeaderLen;
760 else if(XMLUtil::StringEqual(p, cdataHeader, cdataHeaderLen ))
762 XMLText* text = CreateUnlinkedNode<XMLText>(_textPool );
764 returnNode->_parseLineNum = _parseCurLineNum;
766 text->SetCData(
true );
768 else if(XMLUtil::StringEqual(p, dtdHeader, dtdHeaderLen ))
770 returnNode = CreateUnlinkedNode<XMLUnknown>(_commentPool );
771 returnNode->_parseLineNum = _parseCurLineNum;
774 else if(XMLUtil::StringEqual(p, elementHeader, elementHeaderLen ))
776 returnNode = CreateUnlinkedNode<XMLElement>(_elementPool );
777 returnNode->_parseLineNum = _parseCurLineNum;
778 p += elementHeaderLen;
782 returnNode = CreateUnlinkedNode<XMLText>(_textPool );
783 returnNode->_parseLineNum = _parseCurLineNum;
785 _parseCurLineNum = startLine;
788 TIXMLASSERT(returnNode );
795bool XMLDocument::Accept(XMLVisitor* visitor )
const
797 TIXMLASSERT(visitor );
798 if(visitor->VisitEnter(*
this ))
802 if(!node->Accept(visitor ))
808 return visitor->VisitExit(*
this );
814XMLNode::XMLNode(XMLDocument* doc ) :
819 _firstChild(0 ), _lastChild(0 ),
820 _prev(0 ), _next(0 ),
832 _parent->Unlink(
this );
836const char* XMLNode::Value()
const
839 if(this->ToDocument())
841 return _value.GetStr();
844void XMLNode::SetValue(
const char* str,
bool staticMem )
848 _value.SetInternedStr(str );
856XMLNode* XMLNode::DeepClone(XMLDocument* target)
const
858 XMLNode* clone = this->ShallowClone(target);
861 for(
const XMLNode* child = this->FirstChild(); child; child = child->NextSibling())
863 XMLNode* childClone = child->DeepClone(target);
864 TIXMLASSERT(childClone);
865 clone->InsertEndChild(childClone);
870void XMLNode::DeleteChildren()
874 TIXMLASSERT(_lastChild );
875 DeleteChild(_firstChild );
877 _firstChild = _lastChild = 0;
881void XMLNode::Unlink(XMLNode* child )
884 TIXMLASSERT(child->_document == _document );
885 TIXMLASSERT(child->_parent ==
this );
886 if(child == _firstChild )
888 _firstChild = _firstChild->_next;
890 if(child == _lastChild )
892 _lastChild = _lastChild->_prev;
897 child->_prev->_next = child->_next;
901 child->_next->_prev = child->_prev;
905 child->_parent =
nullptr;
909void XMLNode::DeleteChild(XMLNode* node )
912 TIXMLASSERT(node->_document == _document );
913 TIXMLASSERT(node->_parent ==
this );
915 TIXMLASSERT(node->_prev == 0);
916 TIXMLASSERT(node->_next == 0);
917 TIXMLASSERT(node->_parent == 0);
922XMLNode* XMLNode::InsertEndChild(XMLNode* addThis )
924 TIXMLASSERT(addThis );
925 if(addThis->_document != _document )
930 InsertChildPreamble(addThis );
934 TIXMLASSERT(_firstChild );
935 TIXMLASSERT(_lastChild->_next == 0 );
936 _lastChild->_next = addThis;
937 addThis->_prev = _lastChild;
938 _lastChild = addThis;
944 TIXMLASSERT(_firstChild == 0 );
945 _firstChild = _lastChild = addThis;
950 addThis->_parent =
this;
955XMLNode* XMLNode::InsertFirstChild(XMLNode* addThis )
957 TIXMLASSERT(addThis );
958 if(addThis->_document != _document )
963 InsertChildPreamble(addThis );
967 TIXMLASSERT(_lastChild );
968 TIXMLASSERT(_firstChild->_prev == 0 );
970 _firstChild->_prev = addThis;
971 addThis->_next = _firstChild;
972 _firstChild = addThis;
978 TIXMLASSERT(_lastChild == 0 );
979 _firstChild = _lastChild = addThis;
984 addThis->_parent =
this;
989XMLNode* XMLNode::InsertAfterChild(XMLNode* afterThis, XMLNode* addThis )
991 TIXMLASSERT(addThis );
992 if(addThis->_document != _document )
998 TIXMLASSERT(afterThis );
1000 if(afterThis->_parent !=
this )
1002 TIXMLASSERT(
false );
1005 if(afterThis == addThis )
1014 if(afterThis->_next == 0 )
1017 return InsertEndChild(addThis );
1019 InsertChildPreamble(addThis );
1020 addThis->_prev = afterThis;
1021 addThis->_next = afterThis->_next;
1022 afterThis->_next->_prev = addThis;
1023 afterThis->_next = addThis;
1024 addThis->_parent =
this;
1031const XMLElement* XMLNode::FirstChildElement(
const char* name )
const
1033 for(
const XMLNode* node = _firstChild; node; node = node->_next )
1035 const XMLElement* element = node->ToElementWithName(name );
1045const XMLElement* XMLNode::LastChildElement(
const char* name )
const
1047 for(
const XMLNode* node = _lastChild; node; node = node->_prev )
1049 const XMLElement* element = node->ToElementWithName(name );
1059const XMLElement* XMLNode::NextSiblingElement(
const char* name )
const
1061 for(
const XMLNode* node = _next; node; node = node->_next )
1063 const XMLElement* element = node->ToElementWithName(name );
1073const XMLElement* XMLNode::PreviousSiblingElement(
const char* name )
const
1075 for(
const XMLNode* node = _prev; node; node = node->_prev )
1077 const XMLElement* element = node->ToElementWithName(name );
1087char* XMLNode::ParseDeep(
char* p,
StrPair* parentEndTag,
int* curLineNumPtr )
1110 p = _document->Identify(p, &node );
1117 int initialLineNum = node->_parseLineNum;
1120 p = node->ParseDeep(p, &endTag, curLineNumPtr );
1124 if(!_document->Error())
1126 _document->SetError(XML_ERROR_PARSING, initialLineNum, 0);
1135 bool wellLocated = (ToDocument() != 0 );
1140 for(
const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling())
1142 if(!existingNode->ToDeclaration())
1144 wellLocated =
false;
1151 _document->SetError(XML_ERROR_PARSING_DECLARATION, initialLineNum,
"XMLDeclaration value=%s", decl->Value());
1161 if(ele->ClosingType() == XMLElement::CLOSING )
1165 ele->_value.TransferTo(parentEndTag );
1167 node->_memPool->SetTracked();
1174 bool mismatch =
false;
1177 if(ele->ClosingType() == XMLElement::OPEN )
1184 if(ele->ClosingType() != XMLElement::OPEN )
1188 else if(!XMLUtil::StringEqual(endTag.GetStr(), ele->Name()))
1195 _document->SetError(XML_ERROR_MISMATCHED_ELEMENT, initialLineNum,
"XMLElement name=%s", ele->Name());
1200 InsertEndChild(node );
1205void XMLNode::DeleteNode(XMLNode* node )
1211 TIXMLASSERT(node->_document);
1212 if(!node->ToDocument())
1214 node->_document->MarkInUse(node);
1217 MemPool* pool = node->_memPool;
1222void XMLNode::InsertChildPreamble(XMLNode* insertThis )
const
1224 TIXMLASSERT(insertThis );
1225 TIXMLASSERT(insertThis->_document == _document );
1227 if(insertThis->_parent)
1229 insertThis->_parent->Unlink(insertThis );
1233 insertThis->_document->MarkInUse(insertThis);
1234 insertThis->_memPool->SetTracked();
1238const XMLElement* XMLNode::ToElementWithName(
const char* name )
const
1240 const XMLElement* element = this->ToElement();
1249 if(XMLUtil::StringEqual(element->Name(), name ))
1257char* XMLText::ParseDeep(
char* p, StrPair*,
int* curLineNumPtr )
1261 p = _value.ParseText(p,
"]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1264 _document->SetError(XML_ERROR_PARSING_CDATA, _parseLineNum, 0 );
1270 int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES;
1271 if(_document->WhitespaceMode() == COLLAPSE_WHITESPACE )
1273 flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING;
1276 p = _value.ParseText(p,
"<", flags, curLineNumPtr );
1283 _document->SetError(XML_ERROR_PARSING_TEXT, _parseLineNum, 0 );
1290XMLNode* XMLText::ShallowClone(XMLDocument* doc )
const
1296 XMLText* text = doc->NewText(Value());
1297 text->SetCData(this->CData());
1302bool XMLText::ShallowEqual(
const XMLNode* compare )
const
1304 TIXMLASSERT(compare );
1305 const XMLText* text = compare->ToText();
1306 return(text && XMLUtil::StringEqual(text->Value(), Value()));
1310bool XMLText::Accept(XMLVisitor* visitor )
const
1312 TIXMLASSERT(visitor );
1313 return visitor->Visit(*
this );
1319XMLComment::XMLComment(XMLDocument* doc ) : XMLNode(doc )
1324XMLComment::~XMLComment()
1329char* XMLComment::ParseDeep(
char* p, StrPair*,
int* curLineNumPtr )
1332 p = _value.ParseText(p,
"-->", StrPair::COMMENT, curLineNumPtr );
1335 _document->SetError(XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 );
1341XMLNode* XMLComment::ShallowClone(XMLDocument* doc )
const
1347 XMLComment* comment = doc->NewComment(Value());
1352bool XMLComment::ShallowEqual(
const XMLNode* compare )
const
1354 TIXMLASSERT(compare );
1355 const XMLComment* comment = compare->ToComment();
1356 return(comment && XMLUtil::StringEqual(comment->Value(), Value()));
1360bool XMLComment::Accept(XMLVisitor* visitor )
const
1362 TIXMLASSERT(visitor );
1363 return visitor->Visit(*
this );
1369XMLDeclaration::XMLDeclaration(XMLDocument* doc ) : XMLNode(doc )
1374XMLDeclaration::~XMLDeclaration()
1380char* XMLDeclaration::ParseDeep(
char* p, StrPair*,
int* curLineNumPtr )
1383 p = _value.ParseText(p,
"?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1386 _document->SetError(XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 );
1392XMLNode* XMLDeclaration::ShallowClone(XMLDocument* doc )
const
1398 XMLDeclaration* dec = doc->NewDeclaration(Value());
1403bool XMLDeclaration::ShallowEqual(
const XMLNode* compare )
const
1405 TIXMLASSERT(compare );
1406 const XMLDeclaration* declaration = compare->ToDeclaration();
1407 return(declaration && XMLUtil::StringEqual(declaration->Value(), Value()));
1412bool XMLDeclaration::Accept(XMLVisitor* visitor )
const
1414 TIXMLASSERT(visitor );
1415 return visitor->Visit(*
this );
1420XMLUnknown::XMLUnknown(XMLDocument* doc ) : XMLNode(doc )
1425XMLUnknown::~XMLUnknown()
1430char* XMLUnknown::ParseDeep(
char* p, StrPair*,
int* curLineNumPtr )
1433 p = _value.ParseText(p,
">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr );
1436 _document->SetError(XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 );
1442XMLNode* XMLUnknown::ShallowClone(XMLDocument* doc )
const
1448 XMLUnknown* text = doc->NewUnknown(Value());
1453bool XMLUnknown::ShallowEqual(
const XMLNode* compare )
const
1455 TIXMLASSERT(compare );
1456 const XMLUnknown* unknown = compare->ToUnknown();
1457 return(unknown && XMLUtil::StringEqual(unknown->Value(), Value()));
1461bool XMLUnknown::Accept(XMLVisitor* visitor )
const
1463 TIXMLASSERT(visitor );
1464 return visitor->Visit(*
this );
1471 return _name.GetStr();
1476 return _value.GetStr();
1479char* XMLAttribute::ParseDeep(
char* p,
bool processEntities,
int* curLineNumPtr )
1482 p = _name.ParseName(p );
1489 p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr );
1496 p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr );
1497 if(*p !=
'\"' && *p !=
'\'')
1502 char endTag[2] = { *p, 0 };
1505 p = _value.ParseText(p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr );
1510void XMLAttribute::SetName(
const char* n )
1516XMLError XMLAttribute::QueryIntValue(
int* value )
const
1518 if(XMLUtil::ToInt(
Value(), value ))
1522 return XML_WRONG_ATTRIBUTE_TYPE;
1528 if(XMLUtil::ToUnsigned(
Value(), value ))
1532 return XML_WRONG_ATTRIBUTE_TYPE;
1538 if(XMLUtil::ToInt64(
Value(), value))
1542 return XML_WRONG_ATTRIBUTE_TYPE;
1548 if(XMLUtil::ToBool(
Value(), value ))
1552 return XML_WRONG_ATTRIBUTE_TYPE;
1558 if(XMLUtil::ToFloat(
Value(), value ))
1562 return XML_WRONG_ATTRIBUTE_TYPE;
1568 if(XMLUtil::ToDouble(
Value(), value ))
1572 return XML_WRONG_ATTRIBUTE_TYPE;
1585 XMLUtil::ToStr(v, buf, BUF_SIZE );
1586 _value.SetStr(buf );
1593 XMLUtil::ToStr(v, buf, BUF_SIZE );
1594 _value.SetStr(buf );
1601 XMLUtil::ToStr(v, buf, BUF_SIZE);
1610 XMLUtil::ToStr(v, buf, BUF_SIZE );
1611 _value.SetStr(buf );
1617 XMLUtil::ToStr(v, buf, BUF_SIZE );
1618 _value.SetStr(buf );
1624 XMLUtil::ToStr(v, buf, BUF_SIZE );
1625 _value.SetStr(buf );
1631 _closingType(OPEN ),
1637XMLElement::~XMLElement()
1639 while(_rootAttribute )
1641 XMLAttribute* next = _rootAttribute->_next;
1642 DeleteAttribute(_rootAttribute );
1643 _rootAttribute = next;
1650 for(
XMLAttribute* a = _rootAttribute; a; a = a->_next )
1652 if(XMLUtil::StringEqual(a->Name(), name ))
1661const char* XMLElement::Attribute(
const char* name,
const char* value )
const
1668 if(!value || XMLUtil::StringEqual(a->
Value(), value ))
1675int XMLElement::IntAttribute(
const char* name,
int defaultValue)
const
1677 int i = defaultValue;
1678 QueryIntAttribute(name, &i);
1684 unsigned i = defaultValue;
1691 int64_t i = defaultValue;
1698 bool b = defaultValue;
1705 double d = defaultValue;
1712 float f = defaultValue;
1717const char* XMLElement::GetText()
const
1727void XMLElement::SetText(
const char* inText )
1733 XMLText* theText =
GetDocument()->NewText(inText );
1734 InsertFirstChild(theText );
1739void XMLElement::SetText(
int v )
1742 XMLUtil::ToStr(v, buf, BUF_SIZE );
1747void XMLElement::SetText(
unsigned v )
1750 XMLUtil::ToStr(v, buf, BUF_SIZE );
1755void XMLElement::SetText(int64_t v)
1758 XMLUtil::ToStr(v, buf, BUF_SIZE);
1763void XMLElement::SetText(
bool v )
1766 XMLUtil::ToStr(v, buf, BUF_SIZE );
1771void XMLElement::SetText(
float v )
1774 XMLUtil::ToStr(v, buf, BUF_SIZE );
1779void XMLElement::SetText(
double v )
1782 XMLUtil::ToStr(v, buf, BUF_SIZE );
1787XMLError XMLElement::QueryIntText(
int* ival )
const
1792 if(XMLUtil::ToInt(t, ival ))
1796 return XML_CAN_NOT_CONVERT_TEXT;
1798 return XML_NO_TEXT_NODE;
1807 if(XMLUtil::ToUnsigned(t, uval ))
1811 return XML_CAN_NOT_CONVERT_TEXT;
1813 return XML_NO_TEXT_NODE;
1822 if(XMLUtil::ToInt64(t, ival))
1826 return XML_CAN_NOT_CONVERT_TEXT;
1828 return XML_NO_TEXT_NODE;
1837 if(XMLUtil::ToBool(t, bval ))
1841 return XML_CAN_NOT_CONVERT_TEXT;
1843 return XML_NO_TEXT_NODE;
1852 if(XMLUtil::ToDouble(t, dval ))
1856 return XML_CAN_NOT_CONVERT_TEXT;
1858 return XML_NO_TEXT_NODE;
1867 if(XMLUtil::ToFloat(t, fval ))
1871 return XML_CAN_NOT_CONVERT_TEXT;
1873 return XML_NO_TEXT_NODE;
1876int XMLElement::IntText(
int defaultValue)
const
1878 int i = defaultValue;
1885 unsigned i = defaultValue;
1892 int64_t i = defaultValue;
1899 bool b = defaultValue;
1906 double d = defaultValue;
1913 float f = defaultValue;
1919XMLAttribute* XMLElement::FindOrCreateAttribute(
const char* name )
1923 for(attrib = _rootAttribute;
1925 last = attrib, attrib = attrib->_next )
1927 if(XMLUtil::StringEqual(attrib->Name(), name ))
1934 attrib = CreateAttribute();
1935 TIXMLASSERT(attrib );
1938 TIXMLASSERT(last->_next == 0 );
1939 last->_next = attrib;
1943 TIXMLASSERT(_rootAttribute == 0 );
1944 _rootAttribute = attrib;
1946 attrib->SetName(name );
1952void XMLElement::DeleteAttribute(
const char* name )
1954 XMLAttribute* prev = 0;
1955 for(XMLAttribute* a=_rootAttribute; a; a=a->_next )
1957 if(XMLUtil::StringEqual(name, a->
Name()))
1961 prev->_next = a->_next;
1965 _rootAttribute = a->_next;
1967 DeleteAttribute(a );
1975char* XMLElement::ParseAttributes(
char* p,
int* curLineNumPtr )
1977 XMLAttribute* prevAttribute = 0;
1982 p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr );
1985 _document->SetError(XML_ERROR_PARSING_ELEMENT, _parseLineNum,
"XMLElement name=%s",
Name());
1990 if(XMLUtil::IsNameStartChar(*p ))
1992 XMLAttribute* attrib = CreateAttribute();
1993 TIXMLASSERT(attrib );
1994 attrib->_parseLineNum = _document->_parseCurLineNum;
1996 int attrLineNum = attrib->_parseLineNum;
1998 p = attrib->ParseDeep(p, _document->ProcessEntities(), curLineNumPtr );
1999 if(!p || Attribute(attrib->Name()))
2001 DeleteAttribute(attrib );
2002 _document->SetError(XML_ERROR_PARSING_ATTRIBUTE, attrLineNum,
"XMLElement name=%s",
Name());
2012 TIXMLASSERT(prevAttribute->_next == 0 );
2013 prevAttribute->_next = attrib;
2017 TIXMLASSERT(_rootAttribute == 0 );
2018 _rootAttribute = attrib;
2020 prevAttribute = attrib;
2029 else if(*p ==
'/' && *(p+1) ==
'>')
2031 _closingType = CLOSED;
2036 _document->SetError(XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 );
2043void XMLElement::DeleteAttribute(XMLAttribute* attribute )
2049 MemPool* pool = attribute->_memPool;
2050 attribute->~XMLAttribute();
2051 pool->Free(attribute );
2054XMLAttribute* XMLElement::CreateAttribute()
2056 TIXMLASSERT(
sizeof(XMLAttribute ) == _document->_attributePool.ItemSize());
2057 XMLAttribute* attrib =
new(_document->_attributePool.Alloc()) XMLAttribute();
2058 TIXMLASSERT(attrib );
2059 attrib->_memPool = &_document->_attributePool;
2060 attrib->_memPool->SetTracked();
2068char* XMLElement::ParseDeep(
char* p, StrPair* parentEndTag,
int* curLineNumPtr )
2071 p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr );
2078 _closingType = CLOSING;
2082 p = _value.ParseName(p );
2088 p = ParseAttributes(p, curLineNumPtr );
2089 if(!p || !*p || _closingType != OPEN )
2094 p = XMLNode::ParseDeep(p, parentEndTag, curLineNumPtr );
2100XMLNode* XMLElement::ShallowClone(XMLDocument* doc )
const
2106 XMLElement* element = doc->NewElement(Value());
2109 element->SetAttribute(a->
Name(), a->
Value());
2115bool XMLElement::ShallowEqual(
const XMLNode* compare )
const
2117 TIXMLASSERT(compare );
2118 const XMLElement* other = compare->ToElement();
2119 if(other && XMLUtil::StringEqual(other->Name(),
Name()))
2123 const XMLAttribute* b=other->FirstAttribute();
2127 if(!XMLUtil::StringEqual(a->Value(), b->Value()))
2145bool XMLElement::Accept(XMLVisitor* visitor )
const
2147 TIXMLASSERT(visitor );
2148 if(visitor->VisitEnter(*
this, _rootAttribute ))
2152 if(!node->Accept(visitor ))
2158 return visitor->VisitExit(*
this );
2165const char* XMLDocument::_errorNames[XML_ERROR_COUNT] =
2169 "XML_WRONG_ATTRIBUTE_TYPE",
2170 "XML_ERROR_FILE_NOT_FOUND",
2171 "XML_ERROR_FILE_COULD_NOT_BE_OPENED",
2172 "XML_ERROR_FILE_READ_ERROR",
2173 "UNUSED_XML_ERROR_ELEMENT_MISMATCH",
2174 "XML_ERROR_PARSING_ELEMENT",
2175 "XML_ERROR_PARSING_ATTRIBUTE",
2176 "UNUSED_XML_ERROR_IDENTIFYING_TAG",
2177 "XML_ERROR_PARSING_TEXT",
2178 "XML_ERROR_PARSING_CDATA",
2179 "XML_ERROR_PARSING_COMMENT",
2180 "XML_ERROR_PARSING_DECLARATION",
2181 "XML_ERROR_PARSING_UNKNOWN",
2182 "XML_ERROR_EMPTY_DOCUMENT",
2183 "XML_ERROR_MISMATCHED_ELEMENT",
2184 "XML_ERROR_PARSING",
2185 "XML_CAN_NOT_CONVERT_TEXT",
2190XMLDocument::XMLDocument(
bool processEntities, Whitespace whitespaceMode ) :
2193 _processEntities(processEntities ),
2194 _errorID(XML_SUCCESS),
2195 _whitespaceMode(whitespaceMode ),
2199 _parseCurLineNum(0 ),
2211XMLDocument::~XMLDocument()
2217void XMLDocument::MarkInUse(XMLNode* node)
2220 TIXMLASSERT(node->_parent == 0);
2222 for(
int i = 0; i < _unlinked.Size(); ++i)
2224 if(node == _unlinked[i])
2226 _unlinked.SwapRemove(i);
2235 while(_unlinked.Size())
2237 DeleteNode(_unlinked[0]);
2240#ifdef TINYXML2_DEBUG
2241 const bool hadError =
Error();
2245 delete [] _charBuffer;
2249 _textPool.Trace(
"text");
2250 _elementPool.Trace(
"element");
2251 _commentPool.Trace(
"comment");
2252 _attributePool.Trace(
"attribute");
2255#ifdef TINYXML2_DEBUG
2258 TIXMLASSERT(_elementPool.CurrentAllocs() == _elementPool.Untracked());
2259 TIXMLASSERT(_attributePool.CurrentAllocs() == _attributePool.Untracked());
2260 TIXMLASSERT(_textPool.CurrentAllocs() == _textPool.Untracked());
2261 TIXMLASSERT(_commentPool.CurrentAllocs() == _commentPool.Untracked());
2267void XMLDocument::DeepCopy(
XMLDocument* target)
const
2269 TIXMLASSERT(target);
2278 target->InsertEndChild(node->DeepClone(target));
2282XMLElement* XMLDocument::NewElement(
const char* name )
2284 XMLElement* ele = CreateUnlinkedNode<XMLElement>(_elementPool );
2285 ele->SetName(name );
2290XMLComment* XMLDocument::NewComment(
const char* str )
2292 XMLComment* comment = CreateUnlinkedNode<XMLComment>(_commentPool );
2293 comment->SetValue(str );
2298XMLText* XMLDocument::NewText(
const char* str )
2300 XMLText* text = CreateUnlinkedNode<XMLText>(_textPool );
2301 text->SetValue(str );
2306XMLDeclaration* XMLDocument::NewDeclaration(
const char* str )
2308 XMLDeclaration* dec = CreateUnlinkedNode<XMLDeclaration>(_commentPool );
2309 dec->SetValue(str ? str :
"xml version=\"1.0\" encoding=\"UTF-8\"");
2314XMLUnknown* XMLDocument::NewUnknown(
const char* str )
2316 XMLUnknown* unk = CreateUnlinkedNode<XMLUnknown>(_commentPool );
2317 unk->SetValue(str );
2321static FILE* callfopen(
const char* filepath,
const char* mode )
2323 TIXMLASSERT(filepath );
2325#if defined(_MSC_VER) &&(_MSC_VER >= 1400 ) &&(!defined WINCE)
2327 errno_t err = fopen_s(&fp, filepath, mode );
2333 FILE* fp = fopen(filepath, mode );
2338void XMLDocument::DeleteNode(XMLNode* node )
2341 TIXMLASSERT(node->_document ==
this );
2344 node->_parent->DeleteChild(node );
2352 node->_memPool->SetTracked();
2354 XMLNode::DeleteNode(node);
2359XMLError XMLDocument::LoadFile(
const char* filename )
2362 FILE* fp = callfopen(filename,
"rb");
2365 SetError(XML_ERROR_FILE_NOT_FOUND, 0,
"filename=%s", filename ? filename :
"<null>");
2380<
bool = (
sizeof(
unsigned long) >=
sizeof(
int))>
2381struct LongFitsIntoSizeTMinusOne
2383 static bool Fits(
unsigned long value )
2385 return value <(int)-1;
2390struct LongFitsIntoSizeTMinusOne<false>
2392 static bool Fits(
unsigned long )
2398XMLError XMLDocument::LoadFile(FILE* fp )
2402 fseek(fp, 0, SEEK_SET );
2403 if(fgetc(fp ) == EOF && ferror(fp ) != 0 )
2405 SetError(XML_ERROR_FILE_READ_ERROR, 0, 0 );
2409 fseek(fp, 0, SEEK_END );
2410 const long filelength = ftell(fp );
2411 fseek(fp, 0, SEEK_SET );
2412 if(filelength == -1L )
2414 SetError(XML_ERROR_FILE_READ_ERROR, 0, 0 );
2417 TIXMLASSERT(filelength >= 0 );
2419 if(!LongFitsIntoSizeTMinusOne<>::Fits(filelength ))
2422 SetError(XML_ERROR_FILE_READ_ERROR, 0, 0 );
2426 if(filelength == 0 )
2428 SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
2432 const int size = filelength;
2433 TIXMLASSERT(_charBuffer == 0 );
2434 _charBuffer =
new char[size+1];
2435 int read = fread(_charBuffer, 1, size, fp );
2438 SetError(XML_ERROR_FILE_READ_ERROR, 0, 0 );
2442 _charBuffer[size] = 0;
2449XMLError XMLDocument::SaveFile(
const char* filename,
bool compact )
2451 FILE* fp = callfopen(filename,
"w");
2454 SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0,
"filename=%s", filename ? filename :
"<null>");
2457 SaveFile(fp, compact);
2463XMLError XMLDocument::SaveFile(FILE* fp,
bool compact )
2468 XMLPrinter stream(fp, compact );
2474XMLError XMLDocument::Parse(
const char* p,
int len )
2478 if(len == 0 || !p || !*p )
2480 SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
2483 if(len == (
int)(-1))
2487 TIXMLASSERT(_charBuffer == 0 );
2488 _charBuffer =
new char[ len+1 ];
2489 memcpy(_charBuffer, p, len );
2490 _charBuffer[len] = 0;
2499 _elementPool.Clear();
2500 _attributePool.Clear();
2502 _commentPool.Clear();
2508void XMLDocument::Print(XMLPrinter* streamer )
const
2516 XMLPrinter stdoutStreamer(stdout );
2517 Accept(&stdoutStreamer );
2522void XMLDocument::SetError(XMLError error,
int lineNum,
const char* format, ...)
2524 TIXMLASSERT(error >= 0 && error < XML_ERROR_COUNT );
2526 _errorLineNum = lineNum;
2529 int BUFFER_SIZE = 1000;
2530 char* buffer =
new char[BUFFER_SIZE];
2532 TIXML_SNPRINTF(buffer, BUFFER_SIZE,
"Error=%s ErrorID=%d(0x%x) Line number=%d", ErrorIDToName(error),
int(error),
int(error), lineNum);
2536 int len = strlen(buffer);
2537 TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len,
": ");
2538 len = strlen(buffer);
2541 va_start(va, format);
2542 TIXML_VSNPRINTF(buffer + len, BUFFER_SIZE - len, format, va);
2545 _errorStr.SetStr(buffer);
2550const char* XMLDocument::ErrorIDToName(XMLError errorID)
2552 TIXMLASSERT(errorID >= 0 && errorID < XML_ERROR_COUNT );
2553 const char* errorName = _errorNames[errorID];
2554 TIXMLASSERT(errorName && errorName[0]);
2558const char* XMLDocument::ErrorStr()
const
2560 return _errorStr.Empty() ?
"" : _errorStr.GetStr();
2566 printf(
"%s\n", ErrorStr());
2569const char* XMLDocument::ErrorName()
const
2571 return ErrorIDToName(_errorID);
2574void XMLDocument::Parse()
2577 TIXMLASSERT(_charBuffer );
2578 _parseCurLineNum = 1;
2580 char* p = _charBuffer;
2581 p = XMLUtil::SkipWhiteSpace(p, &_parseCurLineNum );
2582 p =
const_cast<char*
>(XMLUtil::ReadBOM(p, &_writeBOM ));
2585 SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0 );
2588 ParseDeep(p, 0, &_parseCurLineNum );
2591XMLPrinter::XMLPrinter(FILE* file,
bool compact,
int depth ) :
2592 _elementJustOpened(false ),
2594 _firstElement(true ),
2598 _processEntities(true ),
2599 _compactMode(compact ),
2602 for(
int i = 0; i <ENTITY_RANGE; ++i )
2604 _entityFlag[i] =
false;
2605 _restrictedEntityFlag[i] =
false;
2607 for(
int i = 0; i <NUM_ENTITIES; ++i )
2609 const char entityValue = entities[i].value;
2610 const unsigned char flagint = (
unsigned char)entityValue;
2611 TIXMLASSERT(flagint < ENTITY_RANGE );
2612 _entityFlag[flagint] =
true;
2614 _restrictedEntityFlag[(
unsigned char)
'&'] =
true;
2615 _restrictedEntityFlag[(
unsigned char)
'<'] =
true;
2616 _restrictedEntityFlag[(
unsigned char)
'>'] =
true;
2621void XMLPrinter::Print(
const char* format, ...)
2624 va_start(va, format );
2628 vfprintf(_fp, format, va );
2632 const int len = TIXML_VSCPRINTF(format, va );
2635 TIXMLASSERT(len >= 0 );
2636 va_start(va, format );
2637 TIXMLASSERT(_buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 );
2638 char* p = _buffer.PushArr(len ) - 1;
2639 TIXML_VSNPRINTF(p, len+1, format, va );
2645void XMLPrinter::Write(
const char* data,
int size )
2649 fwrite(data,
sizeof(
char), size, _fp);
2653 char* p = _buffer.PushArr(
static_cast<int>(size)) - 1;
2654 memcpy(p, data, size );
2660void XMLPrinter::Putc(
char ch )
2668 char* p = _buffer.PushArr(
sizeof(
char)) - 1;
2675void XMLPrinter::PrintSpace(
int depth )
2677 for(
int i = 0; i <depth; ++i )
2684void XMLPrinter::PrintString(
const char* p,
bool restricted )
2689 if(_processEntities )
2691 const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag;
2694 TIXMLASSERT(p <= q );
2696 if(*q > 0 && *q < ENTITY_RANGE )
2701 if(flag[(
unsigned char)(*q)])
2705 const int delta = q - p;
2706 const int toPrint = (INT_MAX < delta ) ? INT_MAX :(
int)delta;
2710 bool entityPatternPrinted =
false;
2711 for(
int i = 0; i <NUM_ENTITIES; ++i )
2713 if(entities[i].value == *q )
2716 Write(entities[i].pattern, entities[i].length );
2718 entityPatternPrinted =
true;
2722 if(!entityPatternPrinted )
2725 TIXMLASSERT(
false );
2731 TIXMLASSERT(p <= q );
2736 TIXMLASSERT(p <= q );
2737 if(!_processEntities ||(p < q ))
2739 const int delta = q - p;
2740 const int toPrint = (INT_MAX < delta ) ? INT_MAX :(
int)delta;
2746void XMLPrinter::PushHeader(
bool writeBOM,
bool writeDec )
2750 static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
2751 Write(
reinterpret_cast< const char*
>(bom ));
2755 PushDeclaration(
"xml version=\"1.0\"");
2760void XMLPrinter::OpenElement(
const char* name,
bool compactMode )
2762 SealElementIfJustOpened();
2765 if(_textDepth < 0 && !_firstElement && !compactMode )
2771 PrintSpace(_depth );
2777 _elementJustOpened =
true;
2778 _firstElement =
false;
2785 TIXMLASSERT(_elementJustOpened );
2789 PrintString(value,
false );
2797 XMLUtil::ToStr(v, buf, BUF_SIZE );
2805 XMLUtil::ToStr(v, buf, BUF_SIZE );
2813 XMLUtil::ToStr(v, buf, BUF_SIZE);
2821 XMLUtil::ToStr(v, buf, BUF_SIZE );
2829 XMLUtil::ToStr(v, buf, BUF_SIZE );
2837 const char* name = _stack.Pop();
2839 if(_elementJustOpened )
2845 if(_textDepth < 0 && !compactMode)
2848 PrintSpace(_depth );
2855 if(_textDepth == _depth )
2859 if(_depth == 0 && !compactMode)
2863 _elementJustOpened =
false;
2867void XMLPrinter::SealElementIfJustOpened()
2869 if(!_elementJustOpened )
2873 _elementJustOpened =
false;
2880 _textDepth = _depth-1;
2882 SealElementIfJustOpened();
2891 PrintString(text,
true );
2898 XMLUtil::ToStr(value, buf, BUF_SIZE );
2905 XMLUtil::ToStr(value, buf, BUF_SIZE );
2913 XMLUtil::ToStr(value, buf, BUF_SIZE );
2921 XMLUtil::ToStr(value, buf, BUF_SIZE );
2929 XMLUtil::ToStr(value, buf, BUF_SIZE );
2937 XMLUtil::ToStr(value, buf, BUF_SIZE );
2944 SealElementIfJustOpened();
2945 if(_textDepth < 0 && !_firstElement && !_compactMode)
2948 PrintSpace(_depth );
2950 _firstElement =
false;
2958void XMLPrinter::PushDeclaration(
const char* value )
2960 SealElementIfJustOpened();
2961 if(_textDepth < 0 && !_firstElement && !_compactMode)
2964 PrintSpace(_depth );
2966 _firstElement =
false;
2974void XMLPrinter::PushUnknown(
const char* value )
2976 SealElementIfJustOpened();
2977 if(_textDepth < 0 && !_firstElement && !_compactMode)
2980 PrintSpace(_depth );
2982 _firstElement =
false;
2992 _processEntities = doc.ProcessEntities();
2995 PushHeader(
true,
false );
3008 const bool compactMode = parentElem ? CompactMode(*parentElem ) : _compactMode;
3009 OpenElement(element.
Name(), compactMode );
3013 attribute = attribute->
Next();
3041 PushDeclaration(declaration.Value());
3048 PushUnknown(unknown.Value());
const XMLAttribute * Next() const
The next attribute in the list.
XMLError QueryUnsignedValue(unsigned int *value) const
See QueryIntValue.
XMLError QueryBoolValue(bool *value) const
See QueryIntValue.
XMLError QueryFloatValue(float *value) const
See QueryIntValue.
const char * Name() const
The name of the attribute.
void SetAttribute(const char *value)
Set the attribute to a string value.
XMLError QueryDoubleValue(double *value) const
See QueryIntValue.
const char * Value() const
The value of the attribute.
XMLError QueryInt64Value(int64_t *value) const
See QueryIntValue.
void Clear()
Clear the document, resetting it to the initial state.
void PrintError() const
A(trivial) utility function that prints the ErrorStr() to stdout.
bool Error() const
Return true if there was an error parsing the document.
XMLError QueryDoubleAttribute(const char *name, double *value) const
See QueryIntAttribute()
bool BoolAttribute(const char *name, bool defaultValue=false) const
See IntAttribute()
float FloatText(float defaultValue=0) const
See QueryIntText()
bool BoolText(bool defaultValue=false) const
See QueryIntText()
int64_t Int64Attribute(const char *name, int64_t defaultValue=0) const
See IntAttribute()
const XMLAttribute * FirstAttribute() const
Return the first attribute in the list.
int64_t Int64Text(int64_t defaultValue=0) const
See QueryIntText()
const char * Name() const
Get the name of an element(which is the Value() of the node.)
XMLError QueryDoubleText(double *dval) const
See QueryIntText()
double DoubleText(double defaultValue=0) const
See QueryIntText()
XMLError QueryFloatText(float *fval) const
See QueryIntText()
const XMLAttribute * FindAttribute(const char *name) const
Query a specific attribute in the list.
XMLError QueryBoolAttribute(const char *name, bool *value) const
See QueryIntAttribute()
unsigned UnsignedAttribute(const char *name, unsigned defaultValue=0) const
See IntAttribute()
double DoubleAttribute(const char *name, double defaultValue=0) const
See IntAttribute()
XMLError QueryInt64Text(int64_t *uval) const
See QueryIntText()
XMLError QueryInt64Attribute(const char *name, int64_t *value) const
See QueryIntAttribute()
float FloatAttribute(const char *name, float defaultValue=0) const
See IntAttribute()
unsigned UnsignedText(unsigned defaultValue=0) const
See QueryIntText()
XMLError QueryUnsignedText(unsigned *uval) const
See QueryIntText()
XMLError QueryBoolText(bool *bval) const
See QueryIntText()
XMLError QueryUnsignedAttribute(const char *name, unsigned int *value) const
See QueryIntAttribute()
XMLError QueryFloatAttribute(const char *name, float *value) const
See QueryIntAttribute()
virtual XMLDeclaration * ToDeclaration()
Safely cast to a Declaration, or null.
bool NoChildren() const
Returns true if this node has no children.
virtual XMLText * ToText()
Safely cast to Text, or null.
const XMLNode * NextSibling() const
Get the next(right) sibling node of this node.
const XMLDocument * GetDocument() const
Get the XMLDocument that owns this XMLNode.
const XMLNode * Parent() const
Get the parent of this node on the DOM.
const XMLNode * FirstChild() const
Get the first child node, or null if none exists.
virtual XMLElement * ToElement()
Safely cast to an Element, or null.
virtual bool Visit(const XMLText &text)
Visit a text node.
void PushText(const char *text, bool cdata=false)
Add a text node.
virtual bool VisitEnter(const XMLDocument &)
Visit a document.
void PushComment(const char *comment)
Add a comment.
void PushAttribute(const char *name, const char *value)
If streaming, add an attribute to an open element.
virtual bool VisitExit(const XMLDocument &)
Visit a document.
virtual void CloseElement(bool compactMode=false)
If streaming, close the Element.
bool CData() const
Returns true if this is a CDATA text element.