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

📄 cpl_minixml.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * * @return a copy of the whole tree.  */CPLXMLNode *CPLCloneXMLTree( CPLXMLNode *psTree ){    CPLXMLNode *psPrevious = NULL;    CPLXMLNode *psReturn = NULL;    while( psTree != NULL )    {        CPLXMLNode *psCopy;        psCopy = CPLCreateXMLNode( NULL, psTree->eType, psTree->pszValue );        if( psReturn == NULL )            psReturn = psCopy;        if( psPrevious != NULL )            psPrevious->psNext = psCopy;        if( psTree->psChild != NULL )            psCopy->psChild = CPLCloneXMLTree( psTree->psChild );        psPrevious = psCopy;        psTree = psTree->psNext;    }    return psReturn;}/************************************************************************//*                           CPLSetXMLValue()                           *//************************************************************************//** * \brief Set element value by path.  * * Find (or create) the target element or attribute specified in the * path, and assign it the indicated value.  * * Any path elements that do not already exist will be created.  The target * nodes value (the first CXT_Text child) will be replaced with the provided * value.   * * If the target node is an attribute instead of an element, the last separator * should be a "#" instead of the normal period path separator.  * * Example: *   CPLSetXMLValue( "Citation.Id.Description", "DOQ dataset" ); *   CPLSetXMLValue( "Citation.Id.Description#name", "doq" ); * * @param psRoot the subdocument to be updated.  * * @param pszPath the dot seperated path to the target element/attribute. * * @param pszValue the text value to assign.  * * @return TRUE on success. */int CPLSetXMLValue( CPLXMLNode *psRoot,  const char *pszPath,                    const char *pszValue ){    char        **papszTokens;    int         iToken = 0;    papszTokens = CSLTokenizeStringComplex( pszPath, ".", FALSE, FALSE );    while( papszTokens[iToken] != NULL && psRoot != NULL )    {        CPLXMLNode *psChild;        int        bIsAttribute = FALSE;        const char *pszName = papszTokens[iToken];        if( pszName[0] == '#' )        {            bIsAttribute = TRUE;            pszName++;        }        if( psRoot->eType != CXT_Element )            return FALSE;        for( psChild = psRoot->psChild; psChild != NULL;              psChild = psChild->psNext )         {            if( psChild->eType != CXT_Text                 && EQUAL(pszName,psChild->pszValue) )                break;        }        if( psChild == NULL )        {            if( bIsAttribute )                psChild = CPLCreateXMLNode( psRoot, CXT_Attribute, pszName );            else                psChild = CPLCreateXMLNode( psRoot, CXT_Element, pszName );        }        psRoot = psChild;        iToken++;    }    CSLDestroy( papszTokens );/* -------------------------------------------------------------------- *//*      Find the "text" child if there is one.                          *//* -------------------------------------------------------------------- */    CPLXMLNode *psTextChild = psRoot->psChild;    while( psTextChild != NULL && psTextChild->eType != CXT_Text )        psTextChild = psTextChild->psNext;/* -------------------------------------------------------------------- *//*      Now set a value node under this node.                           *//* -------------------------------------------------------------------- */        if( psTextChild == NULL )        CPLCreateXMLNode( psRoot, CXT_Text, pszValue );    else     {        CPLFree( psTextChild->pszValue );        psTextChild->pszValue = CPLStrdup( pszValue );    }    return TRUE;}/************************************************************************//*                        CPLStripXMLNamespace()                        *//************************************************************************//** * \brief Strip indicated namespaces.  * * The subdocument (psRoot) is recursively examined, and any elements * with the indicated namespace prefix will have the namespace prefix * stripped from the element names.  If the passed namespace is NULL, then * all namespace prefixes will be stripped.  * * Nodes other than elements should remain unaffected.  The changes are * made "in place", and should not alter any node locations, only the  * pszValue field of affected nodes.  * * @param psRoot the document to operate on. * @param pszNamespace the name space prefix (not including colon), or NULL. * @param bRecurse TRUE to recurse over whole document, or FALSE to only * operate on the passed node. */void CPLStripXMLNamespace( CPLXMLNode *psRoot,                            const char *pszNamespace,                            int bRecurse ){    if( psRoot == NULL )        return;    if( psRoot->eType == CXT_Element || psRoot->eType == CXT_Attribute )    {        if( pszNamespace != NULL )        {            if( EQUALN(pszNamespace,psRoot->pszValue,strlen(pszNamespace))                 && psRoot->pszValue[strlen(pszNamespace)] == ':' )            {                char *pszNewValue =                     CPLStrdup(psRoot->pszValue+strlen(pszNamespace)+1);                                CPLFree( psRoot->pszValue );                psRoot->pszValue = pszNewValue;            }        }        else        {            const char *pszCheck;                        for( pszCheck = psRoot->pszValue; *pszCheck != '\0'; pszCheck++ )            {                if( *pszCheck == ':' )                {                    char *pszNewValue = CPLStrdup( pszCheck+1 );                                        CPLFree( psRoot->pszValue );                    psRoot->pszValue = pszNewValue;                    break;                }            }        }    }    if( bRecurse )    {        if( psRoot->psChild != NULL )            CPLStripXMLNamespace( psRoot->psChild, pszNamespace, 1 );        if( psRoot->psNext != NULL )            CPLStripXMLNamespace( psRoot->psNext, pszNamespace, 1 );    }}/************************************************************************//*                          CPLParseXMLFile()                           *//************************************************************************//** * \brief Parse XML file into tree. * * The named file is opened, loaded into memory as a big string, and * parsed with CPLParseXMLString().  Errors in reading the file or parsing * the XML will be reported by CPLError().  * * The "large file" API is used, so XML files can come from virtualized * files.  * * @param pszFilename the file to open.  * * @return NULL on failure, or the document tree on success. */CPLXMLNode *CPLParseXMLFile( const char *pszFilename ){    FILE            *fp;    vsi_l_offset    nLen;    char            *pszDoc;    CPLXMLNode      *psTree;/* -------------------------------------------------------------------- *//*      Read the file.                                                  *//* -------------------------------------------------------------------- */    fp = VSIFOpenL( pszFilename, "rb" );    if( fp == NULL )    {        CPLError( CE_Failure, CPLE_OpenFailed,                   "Failed to open %.500s to read.", pszFilename );        return NULL;    }    VSIFSeekL( fp, 0, SEEK_END );    nLen = VSIFTellL( fp );    VSIFSeekL( fp, 0, SEEK_SET );        pszDoc = (char *) VSIMalloc((size_t)nLen + 1);    if( pszDoc == NULL )    {        CPLError( CE_Failure, CPLE_OutOfMemory,                   "Out of memory allocating space for %d byte buffer in\n"                  "CPLParseXMLFile(%.500s).",                   nLen+1, pszFilename );        VSIFCloseL( fp );        return NULL;    }    if( VSIFReadL( pszDoc, 1, (size_t)nLen, fp ) < nLen )    {        CPLError( CE_Failure, CPLE_FileIO,                   "VSIFRead() result short of expected %d bytes from %.500s.",                   nLen, pszFilename );        pszDoc[0] = '\0';    }    VSIFCloseL( fp );    pszDoc[nLen] = '\0';/* -------------------------------------------------------------------- *//*      Parse it.                                                       *//* -------------------------------------------------------------------- */    psTree = CPLParseXMLString( pszDoc );    CPLFree( pszDoc );    return psTree;}/************************************************************************//*                     CPLSerializeXMLTreeToFile()                      *//************************************************************************//** * \brief Write document tree to a file.  * * The passed document tree is converted into one big string (with  * CPLSerializeXMLTree()) and then written to the named file.  Errors writing * the file will be reported by CPLError().  The source document tree is * not altered.  If the output file already exists it will be overwritten.  * * @param psTree the document tree to write.  * @param pszFilename the name of the file to write to.  */int CPLSerializeXMLTreeToFile( CPLXMLNode *psTree, const char *pszFilename ){    char    *pszDoc;    FILE    *fp;    vsi_l_offset nLength;/* -------------------------------------------------------------------- *//*      Serialize document.                                             *//* -------------------------------------------------------------------- */    pszDoc = CPLSerializeXMLTree( psTree );    if( pszDoc == NULL )        return FALSE;    nLength = strlen(pszDoc);/* -------------------------------------------------------------------- *//*      Create file.                                                    *//* -------------------------------------------------------------------- */    fp = VSIFOpenL( pszFilename, "wt" );    if( fp == NULL )    {        CPLError( CE_Failure, CPLE_OpenFailed,                   "Failed to open %.500s to write.", pszFilename );        return FALSE;    }/* -------------------------------------------------------------------- *//*      Write file.                                                     *//* -------------------------------------------------------------------- */    if( VSIFWriteL( pszDoc, 1, nLength, fp ) != nLength )    {        CPLError( CE_Failure, CPLE_FileIO,                   "Failed to write whole XML document (%.500s).",                  pszFilename );        VSIFCloseL( fp );        CPLFree( pszDoc );        return FALSE;    }/* -------------------------------------------------------------------- *//*      Cleanup                                                         *//* -------------------------------------------------------------------- */    VSIFCloseL( fp );    CPLFree( pszDoc );    return TRUE;}/************************************************************************//*                       CPLCleanXMLElementName()                       *//************************************************************************//** * \brief Make string into safe XML token. * * Modififies a string in place to try and make it into a legal * XML token that can be used as an element name.   This is accomplished * by changing any characters not legal in a token into an underscore.  *  * NOTE: This function should implement the rules in section 2.3 of  * http://www.w3.org/TR/xml11/ but it doesn't yet do that properly.  We * only do a rough approximation of that. * * @param pszTarget the string to be adjusted.  It is altered in place.  */void CPLCleanXMLElementName( char *pszTarget ){    if( pszTarget == NULL )        return;    for( ; *pszTarget != '\0'; pszTarget++ )    {        if( (*((unsigned char *) pszTarget) & 0x80) || isalnum( *pszTarget )            || *pszTarget == '_' || *pszTarget == '.' )        {            /* ok */        }        else        {            *pszTarget = '_';        }    }}

⌨️ 快捷键说明

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