📄 tinyxmlparsera.cpp
字号:
if ( doc ) doc->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); } return returnNode;}#ifdef TIXMLA_USE_STLvoid TiXmlElementA::StreamIn (TIXMLA_ISTREAM * in, TIXMLA_STRING * tag){ // We're called with some amount of pre-parsing. That is, some of "this" // element is in "tag". Go ahead and stream to the closing ">" while( in->good() ) { int c = in->get(); (*tag) += (char) c ; if ( c == '>' ) break; } if ( tag->length() < 3 ) return; // Okay...if we are a "/>" tag, then we're done. We've read a complete tag. // If not, identify and stream. if ( tag->at( tag->length() - 1 ) == '>' && tag->at( tag->length() - 2 ) == '/' ) { // All good! return; } else if ( tag->at( tag->length() - 1 ) == '>' ) { // There is more. Could be: // text // closing tag // another node. for ( ;; ) { StreamWhiteSpace( in, tag ); // Do we have text? if ( in->good() && in->peek() != '<' ) { // Yep, text. TiXmlTextA text( "" ); text.StreamIn( in, tag ); // What follows text is a closing tag or another node. // Go around again and figure it out. continue; } // We now have either a closing tag...or another node. // We should be at a "<", regardless. if ( !in->good() ) return; assert( in->peek() == '<' ); int tagIndex = tag->length(); bool closingTag = false; bool firstCharFound = false; for( ;; ) { if ( !in->good() ) return; int c = in->peek(); if ( c == '>' ) break; *tag += c; in->get(); if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) ) { firstCharFound = true; if ( c == '/' ) closingTag = true; } } // If it was a closing tag, then read in the closing '>' to clean up the input stream. // If it was not, the streaming will be done by the tag. if ( closingTag ) { int c = in->get(); assert( c == '>' ); *tag += c; // We are done, once we've found our closing tag. return; } else { // If not a closing tag, id it, and stream. const char* tagloc = tag->c_str() + tagIndex; TiXmlNodeA* node = Identify( tagloc ); if ( !node ) return; node->StreamIn( in, tag ); delete node; node = 0; // No return: go around from the beginning: text, closing tag, or node. } } }}#endifconst char* TiXmlElementA::Parse( const char* p, TiXmlParsingDataA* data ){ p = SkipWhiteSpace( p ); TiXmlDocumentA* document = GetDocument(); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, 0, 0 ); return 0; }// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } if ( *p != '<' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, p, data ); return 0; } p = SkipWhiteSpace( p+1 ); // Read the name. const char* pErr = p; p = ReadName( p, &value ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data ); return 0; } TIXMLA_STRING endTag ("</"); endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { pErr = p; p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, pErr, data ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_EMPTY, p, data ); return 0; } return (p+1); } else if ( *p == '>' ) { // Done with attributes (if there were any.) // Read the value -- which can include other // elements -- read the end tag, and return. ++p; p = ReadValue( p, data ); // Note this is an Element method, and will set the error if one happens. if ( !p || !*p ) return 0; // We should find the end tag now if ( StringEqual( p, endTag.c_str(), false ) ) { p += endTag.length(); return p; } else { if ( document ) document->SetError( TIXMLA_ERROR_READING_END_TAG, p, data ); return 0; } } else { // Try to read an attribute: TiXmlAttributeA* attrib = new TiXmlAttributeA(); if ( !attrib ) { if ( document ) document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, pErr, data ); return 0; } attrib->SetDocument( document ); const char* pErr = p; p = attrib->Parse( p, data ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_ELEMENT, pErr, data ); delete attrib; return 0; } // Handle the strange case of double attributes: TiXmlAttributeA* node = attributeSet.Find( attrib->Name() ); if ( node ) { node->SetValue( attrib->Value() ); delete attrib; return 0; } attributeSet.Add( attrib ); } } return p;}const char* TiXmlElementA::ReadValue( const char* p, TiXmlParsingDataA* data ){ TiXmlDocumentA* document = GetDocument(); // Read in text and elements in any order. p = SkipWhiteSpace( p ); while ( p && *p ) { if ( *p != '<' ) { // Take what we have, make a text element. TiXmlTextA* textNode = new TiXmlTextA( "" ); if ( !textNode ) { if ( document ) document->SetError( TIXMLA_ERROR_OUT_OF_MEMORY, 0, 0 ); return 0; } p = textNode->Parse( p, data ); if ( !textNode->Blank() ) LinkEndChild( textNode ); else delete textNode; } else { // We hit a '<' // Have we hit a new element or an end tag? if ( StringEqual( p, "</", false ) ) { return p; } else { TiXmlNodeA* node = Identify( p ); if ( node ) { p = node->Parse( p, data ); LinkEndChild( node ); } else { return 0; } } } p = SkipWhiteSpace( p ); } if ( !p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ELEMENT_VALUE, 0, 0 ); } return p;}#ifdef TIXMLA_USE_STLvoid TiXmlUnknownA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ){ while ( in->good() ) { int c = in->get(); (*tag) += c; if ( c == '>' ) { // All is well. return; } }}#endifconst char* TiXmlUnknownA::Parse( const char* p, TiXmlParsingDataA* data ){ TiXmlDocumentA* document = GetDocument(); p = SkipWhiteSpace( p );// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } if ( !p || !*p || *p != '<' ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_UNKNOWN, p, data ); return 0; } ++p; value = ""; while ( p && *p && *p != '>' ) { value += *p; ++p; } if ( !p ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_UNKNOWN, 0, 0 ); } if ( *p == '>' ) return p+1; return p;}#ifdef TIXMLA_USE_STLvoid TiXmlCommentA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ){ while ( in->good() ) { int c = in->get(); (*tag) += c; if ( c == '>' && tag->at( tag->length() - 2 ) == '-' && tag->at( tag->length() - 3 ) == '-' ) { // All is well. return; } }}#endifconst char* TiXmlCommentA::Parse( const char* p, TiXmlParsingDataA* data ){ TiXmlDocumentA* document = GetDocument(); value = ""; p = SkipWhiteSpace( p );// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } const char* startTag = "<!--"; const char* endTag = "-->"; if ( !StringEqual( p, startTag, false ) ) { document->SetError( TIXMLA_ERROR_PARSING_COMMENT, p, data ); return 0; } p += strlen( startTag ); p = ReadText( p, &value, false, endTag, false ); return p;}const char* TiXmlAttributeA::Parse( const char* p, TiXmlParsingDataA* data ){ p = SkipWhiteSpace( p ); if ( !p || !*p ) return 0; int tabsize = 4; if ( document ) tabsize = document->TabSize();// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } // Read the name, the '=' and the value. const char* pErr = p; p = ReadName( p, &name ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, pErr, data ); return 0; } p = SkipWhiteSpace( p ); if ( !p || !*p || *p != '=' ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, p, data ); return 0; } ++p; // skip '=' p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXMLA_ERROR_READING_ATTRIBUTES, p, data ); return 0; } const char* end; if ( *p == '\'' ) { ++p; end = "\'"; p = ReadText( p, &value, false, end, false ); } else if ( *p == '"' ) { ++p; end = "\""; p = ReadText( p, &value, false, end, false ); } else { // All attribute values should be in single or double quotes. // But this is such a common error that the parser will try // its best, even without them. value = ""; while ( p && *p // existence && !isspace( *p ) && *p != '\n' && *p != '\r' // whitespace && *p != '/' && *p != '>' ) // tag end { value += *p; ++p; } } return p;}#ifdef TIXMLA_USE_STLvoid TiXmlTextA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ){ while ( in->good() ) { int c = in->peek(); if ( c == '<' ) return; (*tag) += c; in->get(); }}#endifconst char* TiXmlTextA::Parse( const char* p, TiXmlParsingDataA* data ){ value = "";// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } bool ignoreWhite = true; const char* end = "<"; p = ReadText( p, &value, ignoreWhite, end, false ); if ( p ) return p-1; // don't truncate the '<' return 0;}#ifdef TIXMLA_USE_STLvoid TiXmlDeclarationA::StreamIn( TIXMLA_ISTREAM * in, TIXMLA_STRING * tag ){ while ( in->good() ) { int c = in->get(); (*tag) += c; if ( c == '>' ) { // All is well. return; } }}#endifconst char* TiXmlDeclarationA::Parse( const char* p, TiXmlParsingDataA* data ){ p = SkipWhiteSpace( p ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocumentA* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml", true ) ) { if ( document ) document->SetError( TIXMLA_ERROR_PARSING_DECLARATION, 0, 0 ); return 0; }// TiXmlParsingDataA data( p, prevData ); if ( data ) { data->Stamp( p ); location = data->Cursor(); } p += 5; version = ""; encoding = ""; standalone = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p ); if ( StringEqual( p, "version", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true ) ) { TiXmlAttributeA attrib; p = attrib.Parse( p, data ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !isspace( *p ) ) ++p; } } return 0;}bool TiXmlTextA::Blank() const{ for ( unsigned i=0; i<value.length(); i++ ) if ( !isspace( value[i] ) ) return false; return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -