📄 cpl_minixml.cpp
字号:
return pszDefault; if( psTarget->eType == CXT_Attribute ) { CPLAssert( psTarget->psChild != NULL && psTarget->psChild->eType == CXT_Text ); return psTarget->psChild->pszValue; } if( psTarget->eType == CXT_Element && psTarget->psChild != NULL && psTarget->psChild->eType == CXT_Text && psTarget->psChild->psNext == NULL ) { return psTarget->psChild->pszValue; } return pszDefault;}/************************************************************************//* CPLAddXMLChild() *//* *//* Add a node as a child of another. Ensure that attributes *//* are inserted ahead of element children, or Text data. *//************************************************************************/void CPLAddXMLChild( CPLXMLNode *psParent, CPLXMLNode *psChild ){ CPLXMLNode *psSib; CPLAssert( psChild->psNext == NULL ); psChild->psNext = NULL; if( psParent->psChild == NULL ) { psParent->psChild = psChild; return; } // Insert at head of list if first child is not attribute. if( psChild->eType == CXT_Attribute && psParent->psChild->eType != CXT_Attribute ) { psChild->psNext = psParent->psChild; psParent->psChild = psChild; return; } // Search for end of list. for( psSib = psParent->psChild; psSib->psNext != NULL; psSib = psSib->psNext ) { // Insert attributes if the next node is not an attribute. if( psChild->eType == CXT_Attribute && psSib->psNext != NULL && psSib->psNext->eType != CXT_Attribute ) { psChild->psNext = psSib->psNext; psSib->psNext = psChild; return; } } psSib->psNext = psChild;}/************************************************************************//* CPLCreateXMLElementAndValue() *//************************************************************************/CPLXMLNode *CPLCreateXMLElementAndValue( CPLXMLNode *psParent, const char *pszName, const char *pszValue ){ return CPLCreateXMLNode( CPLCreateXMLNode( psParent, CXT_Element, pszName ), CXT_Text, pszValue );}/************************************************************************//* CPLCloneXMLTree() *//* *//* Clone an XML Tree. We use recursion to handle children, but *//* we do siblings by looping. This means we can handle very *//* long lists of elements, but great depth may cause stack *//* overflow problems on some systems. *//************************************************************************/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() *//* *//* Set the text value of an XML element to the suggested *//* value. Intermediate element nodes are created if *//* an existing component is missing. *//************************************************************************/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 );/* -------------------------------------------------------------------- *//* Now set a value node under this node. *//* -------------------------------------------------------------------- */ if( psRoot->psChild == NULL ) CPLCreateXMLNode( psRoot, CXT_Text, pszValue ); else if( psRoot->psChild->eType != CXT_Text ) return FALSE; else { CPLFree( psRoot->psChild->pszValue ); psRoot->psChild->pszValue = CPLStrdup( pszValue ); } return TRUE;}/************************************************************************//* CPLStripXMLNamespace() *//************************************************************************/void CPLStripXMLNamespace( CPLXMLNode *psRoot, const char *pszNamespace, int bRecurse ){ if( psRoot == NULL ) return; if( pszNamespace != NULL ) { if( psRoot->eType == CXT_Element && 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() *//************************************************************************/CPLXMLNode *CPLParseXMLFile( const char *pszFilename ){ FILE *fp; int nLen; char *pszDoc; CPLXMLNode *psTree;/* -------------------------------------------------------------------- *//* Read the file. *//* -------------------------------------------------------------------- */ fp = VSIFOpen( pszFilename, "rb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %.500s to read.", pszFilename ); return NULL; } VSIFSeek( fp, 0, SEEK_END ); nLen = VSIFTell( fp ); VSIFSeek( fp, 0, SEEK_SET ); pszDoc = (char *) VSIMalloc(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 ); VSIFClose( fp ); return NULL; } if( (int) VSIFRead( pszDoc, 1, nLen, fp ) < nLen ) { CPLError( CE_Failure, CPLE_FileIO, "VSIFRead() result short of expected %d bytes from %.500s.", nLen, pszFilename ); pszDoc[0] = '\0'; } VSIFClose( fp ); pszDoc[nLen] = '\0';/* -------------------------------------------------------------------- *//* Parse it. *//* -------------------------------------------------------------------- */ psTree = CPLParseXMLString( pszDoc ); CPLFree( pszDoc ); return psTree;}/************************************************************************//* CPLSerializeXMLTreeToFile() *//************************************************************************/int CPLSerializeXMLTreeToFile( CPLXMLNode *psTree, const char *pszFilename ){ char *pszDoc; FILE *fp; int nLength;/* -------------------------------------------------------------------- *//* Serialize document. *//* -------------------------------------------------------------------- */ pszDoc = CPLSerializeXMLTree( psTree ); if( pszDoc == NULL ) return FALSE; nLength = strlen(pszDoc);/* -------------------------------------------------------------------- *//* Create file. *//* -------------------------------------------------------------------- */ fp = VSIFOpen( pszFilename, "wt" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %.500s to write.", pszFilename ); return FALSE; }/* -------------------------------------------------------------------- *//* Write file. *//* -------------------------------------------------------------------- */ if( (int) VSIFWrite( pszDoc, 1, nLength, fp ) != nLength ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to write whole XML document (%.500s).", pszFilename ); VSIFClose( fp ); CPLFree( pszDoc ); return FALSE; }/* -------------------------------------------------------------------- *//* Cleanup *//* -------------------------------------------------------------------- */ VSIFClose( fp ); CPLFree( pszDoc ); return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -