⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tinyxmlparser.c

📁 一个简单的xml解析代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            // Do we have text?            if( in->good() && in->peek() != '<' ) {                // Yep, text.                TiXmlText 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;                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.            }        }    }}#endifconst 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(const char*)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(const char*)false;    }    TIXML_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 ) {        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;}#ifdef TIXML_USE_STLvoid TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) {    while( in->good() ) {        int c = in->get();          (*tag) += c;        if( c == '>' ) {            // All is well.            return;             }    }}#endifconst 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;}#ifdef TIXML_USE_STLvoid TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_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* 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;}#ifdef TIXML_USE_STLvoid TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) {    while( in->good() ) {        int c = in->peek();         if( c == '<' )            return;        (*tag) += c;        in->get();    }}#endifconst 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;}#ifdef TIXML_USE_STLvoid TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag ) {    while( in->good() ) {        int c = in->get();        (*tag) += c;        if( c == '>' ) {            // All is well.            return;        }    }}#endifconst 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.length(); i++ )        if( !isspace( value[i] ) )            return false;    return true;}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -