📄 tinyxmlparser.cpp
字号:
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; TiXmlNode* 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. } } }}const char* TiXmlElement::Parse( const char* p ){ p = SkipWhiteSpace( p ); TiXmlDocument* document = GetDocument(); if ( !p || !*p || *p != '<' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT ); return false; } p = SkipWhiteSpace( p+1 ); // Read the name. p = ReadName( p, &value ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME ); return false; } string endTag = "</"; endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while ( p && *p ) { p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } if ( *p == '/' ) { ++p; // Empty tag. if ( *p != '>' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY ); 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 ); // 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( TIXML_ERROR_READING_END_TAG ); return 0; } } else { // Try to read an element: TiXmlAttribute attrib; attrib.SetDocument( document ); p = attrib.Parse( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT ); return 0; } SetAttribute( attrib.Name(), attrib.Value() ); } } return p;}const char* TiXmlElement::ReadValue( const char* p ){ TiXmlDocument* document = GetDocument(); // Read in text and elements in any order. p = SkipWhiteSpace( p ); while ( p && *p ) {// string text;// while ( p && *p && *p != '<' )// {// text += (*p);// ++p;// }//// p = SkipWhiteSpace( p ); if ( *p != '<' ) { // Take what we have, make a text element. TiXmlText* textNode = new TiXmlText( "" ); if ( !textNode ) { if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY ); return 0; } p = textNode->Parse( p ); 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 { TiXmlNode* node = Identify( p ); if ( node ) { p = node->Parse( p ); LinkEndChild( node ); } else { return 0; } } } p = SkipWhiteSpace( p ); } if ( !p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE ); } return p;}void TiXmlUnknown::StreamIn( std::istream* in, std::string* tag ){ while ( in->good() ) { int c = in->get(); (*tag) += c; if ( c == '>' ) { // All is well. return; } }}const char* TiXmlUnknown::Parse( const char* p ){ TiXmlDocument* document = GetDocument(); p = SkipWhiteSpace( p ); if ( !p || !*p || *p != '<' ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN ); return 0; } ++p; value = ""; while ( p && *p && *p != '>' ) { value += *p; ++p; } if ( !p ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN ); } if ( *p == '>' ) return p+1; return p;}void TiXmlComment::StreamIn( std::istream* in, std::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; } }}const char* TiXmlComment::Parse( const char* p ){ TiXmlDocument* document = GetDocument(); value = ""; p = SkipWhiteSpace( p ); const char* startTag = "<!--"; const char* endTag = "-->"; if ( !StringEqual( p, startTag, false ) ) { document->SetError( TIXML_ERROR_PARSING_COMMENT ); return 0; } p += strlen( startTag ); p = ReadText( p, &value, false, endTag, false ); return p;}const char* TiXmlAttribute::Parse( const char* p ){ p = SkipWhiteSpace( p ); if ( !p || !*p ) return 0; // Read the name, the '=' and the value. p = ReadName( p, &name ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } p = SkipWhiteSpace( p ); if ( !p || !*p || *p != '=' ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); return 0; } ++p; // skip '=' p = SkipWhiteSpace( p ); if ( !p || !*p ) { if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES ); 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;}void TiXmlText::StreamIn( std::istream* in, std::string* tag ){ while ( in->good() ) { int c = in->peek(); if ( c == '<' ) return; (*tag) += c; in->get(); }}const char* TiXmlText::Parse( const char* p ){ value = ""; //TiXmlDocument* doc = GetDocument(); bool ignoreWhite = true;// if ( doc && !doc->IgnoreWhiteSpace() ) ignoreWhite = false; const char* end = "<"; p = ReadText( p, &value, ignoreWhite, end, false ); if ( p ) return p-1; // don't truncate the '<' return 0;}void TiXmlDeclaration::StreamIn( std::istream* in, std::string* tag ){ while ( in->good() ) { int c = in->get(); (*tag) += c; if ( c == '>' ) { // All is well. return; } }}const char* TiXmlDeclaration::Parse( const char* p ){ p = SkipWhiteSpace( p ); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument* document = GetDocument(); if ( !p || !*p || !StringEqual( p, "<?xml", true ) ) { if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION ); return 0; } p += 5;// const char* start = p+5;// const char* end = strstr( start, "?>" ); version = ""; encoding = ""; standalone = ""; while ( p && *p ) { if ( *p == '>' ) { ++p; return p; } p = SkipWhiteSpace( p ); if ( StringEqual( p, "version", true ) ) {// p += 7; TiXmlAttribute attrib; p = attrib.Parse( p ); version = attrib.Value(); } else if ( StringEqual( p, "encoding", true ) ) {// p += 8; TiXmlAttribute attrib; p = attrib.Parse( p ); encoding = attrib.Value(); } else if ( StringEqual( p, "standalone", true ) ) {// p += 10; TiXmlAttribute attrib; p = attrib.Parse( p ); standalone = attrib.Value(); } else { // Read over whatever it is. while( p && *p && *p != '>' && !isspace( *p ) ) ++p; } } return 0;}bool TiXmlText::Blank() const{ for ( unsigned i=0; i<value.size(); i++ ) if ( !isspace( value[i] ) ) return false; return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -