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

📄 cpl_minixml.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    else if( psContext->bInElement && chNext == '\'' )    {        psContext->eTokenType = TString;        while( (chNext = ReadChar(psContext)) != '\''                && chNext != '\0' )            AddToToken( psContext, chNext );                if( chNext != '\'' )        {            psContext->eTokenType = TNone;            CPLError( CE_Failure, CPLE_AppDefined,                   "Parse error on line %d, reached EOF before closing quote.",                       psContext->nInputLine );        }        /* Do we need to unescape it? */        if( strchr(psContext->pszToken,'&') != NULL )        {            int  nLength;            char *pszUnescaped = CPLUnescapeString( psContext->pszToken,                                                     &nLength, CPLES_XML );            strcpy( psContext->pszToken, pszUnescaped );            CPLFree( pszUnescaped );            psContext->nTokenSize = strlen(psContext->pszToken );        }    }/* -------------------------------------------------------------------- *//*      Collect an unquoted string, terminated by a open angle          *//*      bracket.                                                        *//* -------------------------------------------------------------------- */    else if( !psContext->bInElement )    {        psContext->eTokenType = TString;        AddToToken( psContext, chNext );        while( (chNext = ReadChar(psContext)) != '<'                && chNext != '\0' )            AddToToken( psContext, chNext );        UnreadChar( psContext, chNext );        /* Do we need to unescape it? */        if( strchr(psContext->pszToken,'&') != NULL )        {            int  nLength;            char *pszUnescaped = CPLUnescapeString( psContext->pszToken,                                                     &nLength, CPLES_XML );            strcpy( psContext->pszToken, pszUnescaped );            CPLFree( pszUnescaped );            psContext->nTokenSize = strlen(psContext->pszToken );        }    }    /* -------------------------------------------------------------------- *//*      Collect a regular token terminated by white space, or           *//*      special character(s) like an equal sign.                        *//* -------------------------------------------------------------------- */    else    {        psContext->eTokenType = TToken;        /* add the first character to the token regardless of what it is */        AddToToken( psContext, chNext );        for( chNext = ReadChar(psContext);              (chNext >= 'A' && chNext <= 'Z')                 || (chNext >= 'a' && chNext <= 'z')                 || chNext == '-'                 || chNext == '_'                 || chNext == '.'                 || chNext == ':'                 || (chNext >= '0' && chNext <= '9');             chNext = ReadChar(psContext) )         {            AddToToken( psContext, chNext );        }        UnreadChar(psContext, chNext);    }        return psContext->eTokenType;}    /************************************************************************//*                              PushNode()                              *//************************************************************************/static void PushNode( ParseContext *psContext, CPLXMLNode *psNode ){    if( psContext->nStackMaxSize <= psContext->nStackSize )    {        psContext->nStackMaxSize += 10;        psContext->papsStack = (CPLXMLNode **)            CPLRealloc(psContext->papsStack,                        sizeof(CPLXMLNode*) * psContext->nStackMaxSize);    }    psContext->papsStack[psContext->nStackSize++] = psNode;}    /************************************************************************//*                             AttachNode()                             *//*                                                                      *//*      Attach the passed node as a child of the current node.          *//*      Special handling exists for adding siblings to psFirst if       *//*      there is nothing on the stack.                                  *//************************************************************************/static void AttachNode( ParseContext *psContext, CPLXMLNode *psNode ){    if( psContext->psFirstNode == NULL )        psContext->psFirstNode = psNode;    else if( psContext->nStackSize == 0 )    {        CPLXMLNode *psSibling;        psSibling = psContext->psFirstNode;        while( psSibling->psNext != NULL )            psSibling = psSibling->psNext;        psSibling->psNext = psNode;    }    else if( psContext->papsStack[psContext->nStackSize-1]->psChild == NULL )    {        psContext->papsStack[psContext->nStackSize-1]->psChild = psNode;    }    else    {        CPLXMLNode *psSibling;        psSibling = psContext->papsStack[psContext->nStackSize-1]->psChild;        while( psSibling->psNext != NULL )            psSibling = psSibling->psNext;        psSibling->psNext = psNode;    }}/************************************************************************//*                         CPLParseXMLString()                          *//************************************************************************//** * \brief Parse an XML string into tree form. * * The passed document is parsed into a CPLXMLNode tree representation.  * If the document is not well formed XML then NULL is returned, and errors * are reported via CPLError().  No validation beyond wellformedness is * done.  The CPLParseXMLFile() convenience function can be used to parse * from a file.  * * The returned document tree is is owned by the caller and should be freed * with CPLDestroyXMLNode() when no longer needed. * * If the document has more than one "root level" element then those after the  * first will be attached to the first as siblings (via the psNext pointers) * even though there is no common parent.  A document with no XML structure * (no angle brackets for instance) would be considered well formed, and  * returned as a single CXT_Text node.   *  * @param pszString the document to parse.  * * @return parsed tree or NULL on error.  */CPLXMLNode *CPLParseXMLString( const char *pszString ){    ParseContext sContext;    CPLErrorReset();    if( pszString == NULL )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "CPLParseXMLString() called with NULL pointer." );        return NULL;    }/* -------------------------------------------------------------------- *//*      Initialize parse context.                                       *//* -------------------------------------------------------------------- */    sContext.pszInput = pszString;    sContext.nInputOffset = 0;    sContext.nInputLine = 0;    sContext.bInElement = FALSE;    sContext.pszToken = NULL;    sContext.nTokenMaxSize = 0;    sContext.nTokenSize = 0;    sContext.eTokenType = TNone;    sContext.nStackMaxSize = 0;    sContext.nStackSize = 0;    sContext.papsStack = NULL;    sContext.psFirstNode = NULL;    /* ensure token is initialized */    AddToToken( &sContext, ' ' );    /* ==================================================================== *//*      Loop reading tokens.                                            *//* ==================================================================== */    while( ReadToken( &sContext ) != TNone )    {/* -------------------------------------------------------------------- *//*      Create a new element.                                           *//* -------------------------------------------------------------------- */        if( sContext.eTokenType == TOpen )        {            CPLXMLNode *psElement;            if( ReadToken(&sContext) != TToken )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Didn't find element token after open angle bracket.",                          sContext.nInputLine );                break;            }            if( sContext.pszToken[0] != '/' )            {                psElement = CPLCreateXMLNode( NULL, CXT_Element,                                              sContext.pszToken );                AttachNode( &sContext, psElement );                PushNode( &sContext, psElement );            }            else             {                if( sContext.nStackSize == 0                    || !EQUAL(sContext.pszToken+1,                         sContext.papsStack[sContext.nStackSize-1]->pszValue) )                {                    CPLError( CE_Failure, CPLE_AppDefined,                               "Line %d: <%.500s> doesn't have matching <%.500s>.",                              sContext.nInputLine,                              sContext.pszToken, sContext.pszToken+1 );                    break;                }                else                {                    if( ReadToken(&sContext) != TClose )                    {                        CPLError( CE_Failure, CPLE_AppDefined,                                   "Line %d: Missing close angle bracket after <%.500s.",                                  sContext.nInputLine,                                  sContext.pszToken );                        break;                    }                    /* pop element off stack */                    sContext.nStackSize--;                }            }        }/* -------------------------------------------------------------------- *//*      Add an attribute to a token.                                    *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TToken )        {            CPLXMLNode *psAttr;            psAttr = CPLCreateXMLNode(NULL, CXT_Attribute, sContext.pszToken);            AttachNode( &sContext, psAttr );                        if( ReadToken(&sContext) != TEqual )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Didn't find expected '=' for value of attribute '%.500s'.",                          sContext.nInputLine, psAttr->pszValue );                break;            }            if( ReadToken(&sContext) != TString                 && sContext.eTokenType != TToken )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Didn't find expected attribute value.",                          sContext.nInputLine );                break;            }            CPLCreateXMLNode( psAttr, CXT_Text, sContext.pszToken );        }/* -------------------------------------------------------------------- *//*      Close the start section of an element.                          *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TClose )        {            if( sContext.nStackSize == 0 )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Found unbalanced '>'.",                          sContext.nInputLine );                break;            }        }/* -------------------------------------------------------------------- *//*      Close the start section of an element, and pop it               *//*      immediately.                                                    *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TSlashClose )        {            if( sContext.nStackSize == 0 )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Found unbalanced '/>'.",                          sContext.nInputLine );                break;            }            sContext.nStackSize--;        }/* -------------------------------------------------------------------- *//*      Close the start section of a <?...?> element, and pop it        *//*      immediately.                                                    *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TQuestionClose )        {            if( sContext.nStackSize == 0 )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Found unbalanced '?>'.",                          sContext.nInputLine );                break;            }            else if( sContext.papsStack[sContext.nStackSize-1]->pszValue[0] != '?' )            {                CPLError( CE_Failure, CPLE_AppDefined,                           "Line %d: Found '?>' without matching '<?'.",                          sContext.nInputLine );                break;            }            sContext.nStackSize--;        }/* -------------------------------------------------------------------- *//*      Handle comments.  They are returned as a whole token with the     *//*      prefix and postfix omitted.  No processing of white space       *//*      will be done.                                                   *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TComment )        {            CPLXMLNode *psValue;            psValue = CPLCreateXMLNode(NULL, CXT_Comment, sContext.pszToken);            AttachNode( &sContext, psValue );        }/* -------------------------------------------------------------------- *//*      Handle literals.  They are returned without processing.         *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TLiteral )        {            CPLXMLNode *psValue;            psValue = CPLCreateXMLNode(NULL, CXT_Literal, sContext.pszToken);            AttachNode( &sContext, psValue );        }/* -------------------------------------------------------------------- *//*      Add a text value node as a child of the current element.        *//* -------------------------------------------------------------------- */        else if( sContext.eTokenType == TString && !sContext.bInElement )        {            CPLXMLNode *psValue;            psValue = CPLCreateXMLNode(NULL, CXT_Text, sContext.pszToken);            AttachNode( &sContext, psValue );        }

⌨️ 快捷键说明

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