CPLXMLNode *GDALPamRasterBand::SerializeToXML( const char *pszUnused ) { if( psPam == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Setup root node and attributes. */ /* -------------------------------------------------------------------- */ CPLString oFmt; CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "PAMRasterBand" ); if( GetBand() > 0 ) CPLSetXMLValue( psTree, "#band", oFmt.Printf( "%d", GetBand() ) ); /* -------------------------------------------------------------------- */ /* Serialize information of interest. */ /* -------------------------------------------------------------------- */ if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( psPam->bNoDataValueSet ) { if (CPLIsNan(psPam->dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan" ); else CPLSetXMLValue( psTree, "NoDataValue", oFmt.Printf( "%.14E", psPam->dfNoDataValue ) ); /* hex encode real floating point values */ if( psPam->dfNoDataValue != floor(psPam->dfNoDataValue) || psPam->dfNoDataValue != atof(oFmt) ) { double dfNoDataLittleEndian; dfNoDataLittleEndian = psPam->dfNoDataValue; CPL_LSBPTR64( &dfNoDataLittleEndian ); char *pszHexEncoding = CPLBinaryToHex( 8, (GByte *) &dfNoDataLittleEndian ); CPLSetXMLValue( psTree, "NoDataValue.#le_hex_equiv",pszHexEncoding); CPLFree( pszHexEncoding ); } } if( psPam->pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", psPam->pszUnitType ); if( psPam->dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", oFmt.Printf( "%.16g", psPam->dfOffset ) ); if( psPam->dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", oFmt.Printf( "%.16g", psPam->dfScale ) ); if( psPam->eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( psPam->eColorInterp )); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( psPam->papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); for( int iEntry=0; psPam->papszCategoryNames[iEntry] != NULL; iEntry++) { CPLCreateXMLElementAndValue( psCT_XML, "Category", psPam->papszCategoryNames[iEntry] ); } } /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( psPam->poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); for( int iEntry=0; iEntry < psPam->poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( psCT_XML, CXT_Element, "Entry" ); psPam->poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", oFmt.Printf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", oFmt.Printf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", oFmt.Printf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", oFmt.Printf("%d",sEntry.c4) ); } } /* -------------------------------------------------------------------- */ /* Min/max. */ /* -------------------------------------------------------------------- */ if( psPam->bHaveMinMax ) { CPLSetXMLValue( psTree, "Minimum", oFmt.Printf( "%.16g", psPam->dfMin ) ); CPLSetXMLValue( psTree, "Maximum", oFmt.Printf( "%.16g", psPam->dfMax ) ); } /* -------------------------------------------------------------------- */ /* Statistics */ /* -------------------------------------------------------------------- */ if( psPam->bHaveStats ) { CPLSetXMLValue( psTree, "Mean", oFmt.Printf( "%.16g", psPam->dfMean ) ); CPLSetXMLValue( psTree, "StandardDeviation", oFmt.Printf( "%.16g", psPam->dfStdDev ) ); } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psPam->psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psPam->psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Raster Attribute Table */ /* -------------------------------------------------------------------- */ if( psPam->poDefaultRAT != NULL ) CPLAddXMLChild( psTree, psPam->poDefaultRAT->Serialize() ); /* -------------------------------------------------------------------- */ /* Metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; psMD = oMDMD.Serialize(); if( psMD != NULL ) { if( psMD->psChild == NULL ) CPLDestroyXMLNode( psMD ); else CPLAddXMLChild( psTree, psMD ); } /* -------------------------------------------------------------------- */ /* We don't want to return anything if we had no metadata to */ /* attach. */ /* -------------------------------------------------------------------- */ if( psTree->psChild == NULL || psTree->psChild->psNext == NULL ) { CPLDestroyXMLNode( psTree ); psTree = NULL; } return psTree; }
static CPLXMLNode * GetDictionaryItem( char **papszGMLMetadata, const char *pszURN ) { char *pszLabel; const char *pszFragmentId = NULL; int i; if( EQUALN(pszURN,"urn:jp2k:xml:", 13) ) pszLabel = CPLStrdup( pszURN + 13 ); else if( EQUALN(pszURN,"urn:ogc:tc:gmljp2:xml:", 22) ) pszLabel = CPLStrdup( pszURN + 22 ); else if( EQUALN(pszURN,"gmljp2://xml/",13) ) pszLabel = CPLStrdup( pszURN + 13 ); else pszLabel = CPLStrdup( pszURN ); /* -------------------------------------------------------------------- */ /* Split out label and fragment id. */ /* -------------------------------------------------------------------- */ for( i = 0; pszLabel[i] != '#'; i++ ) { if( pszLabel[i] == '\0' ) return NULL; } pszFragmentId = pszLabel + i + 1; pszLabel[i] = '\0'; /* -------------------------------------------------------------------- */ /* Can we find an XML box with the desired label? */ /* -------------------------------------------------------------------- */ const char *pszDictionary = CSLFetchNameValue( papszGMLMetadata, pszLabel ); if( pszDictionary == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Try and parse the dictionary. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDictTree = CPLParseXMLString( pszDictionary ); if( psDictTree == NULL ) { CPLDestroyXMLNode( psDictTree ); return NULL; } CPLStripXMLNamespace( psDictTree, NULL, TRUE ); CPLXMLNode *psDictRoot = CPLSearchXMLNode( psDictTree, "=Dictionary" ); if( psDictRoot == NULL ) { CPLDestroyXMLNode( psDictTree ); return NULL; } /* -------------------------------------------------------------------- */ /* Search for matching id. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psEntry, *psHit = NULL; for( psEntry = psDictRoot->psChild; psEntry != NULL && psHit == NULL; psEntry = psEntry->psNext ) { const char *pszId; if( psEntry->eType != CXT_Element ) continue; if( !EQUAL(psEntry->pszValue,"dictionaryEntry") ) continue; if( psEntry->psChild == NULL ) continue; pszId = CPLGetXMLValue( psEntry->psChild, "id", "" ); if( EQUAL(pszId, pszFragmentId) ) psHit = CPLCloneXMLTree( psEntry->psChild ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( pszLabel ); CPLDestroyXMLNode( psDictTree ); return psHit; }
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree, const char *pszUnused ) { PamInitialize(); /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ GDALMajorObject::SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL ) { const char *pszLEHex = CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", NULL ); if( pszLEHex != NULL ) { int nBytes; GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes ); if( nBytes == 8 ) { CPL_LSBPTR64( pabyBin ); GDALPamRasterBand::SetNoDataValue( *((double *) pabyBin) ); } else { GDALPamRasterBand::SetNoDataValue( atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } CPLFree( pabyBin ); } else { GDALPamRasterBand::SetNoDataValue( atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } } GDALPamRasterBand::SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); GDALPamRasterBand::SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL)); if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL ); GDALPamRasterBand::SetColorInterpretation( GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL ) { CPLXMLNode *psEntry; char **papszCategoryNames = NULL; for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { /* Don't skeep <Category> tag with empty content */ if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) ) continue; papszCategoryNames = CSLAddString( papszCategoryNames, (psEntry->psChild) ? psEntry->psChild->pszValue : "" ); } GDALPamRasterBand::SetCategoryNames( papszCategoryNames ); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL ) { CPLXMLNode *psEntry; GDALColorTable oTable; int iEntry = 0; for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { GDALColorEntry sCEntry; sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" )); sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" )); sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" )); sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" )); oTable.SetColorEntry( iEntry++, &sCEntry ); } GDALPamRasterBand::SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Do we have a complete set of stats? */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "Minimum" ) != NULL && CPLGetXMLNode( psTree, "Maximum" ) != NULL ) { psPam->bHaveMinMax = TRUE; psPam->dfMin = atof(CPLGetXMLValue(psTree, "Minimum","0")); psPam->dfMax = atof(CPLGetXMLValue(psTree, "Maximum","0")); } if( CPLGetXMLNode( psTree, "Mean" ) != NULL && CPLGetXMLNode( psTree, "StandardDeviation" ) != NULL ) { psPam->bHaveStats = TRUE; psPam->dfMean = atof(CPLGetXMLValue(psTree, "Mean","0")); psPam->dfStdDev = atof(CPLGetXMLValue(psTree,"StandardDeviation","0")); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != NULL ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = NULL; psPam->psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* -------------------------------------------------------------------- */ /* Raster Attribute Table */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" ); if( psRAT != NULL ) { psPam->poDefaultRAT = new GDALRasterAttributeTable(); psPam->poDefaultRAT->XMLInit( psRAT, "" ); } return CE_None; }
CPLXMLNode *VRTRasterBand::SerializeToXML( const char *pszVRTPath ) { CPLXMLNode *psTree; psTree = CPLCreateXMLNode( NULL, CXT_Element, "VRTRasterBand" ); /* -------------------------------------------------------------------- */ /* Various kinds of metadata. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMD; CPLSetXMLValue( psTree, "#dataType", GDALGetDataTypeName( GetRasterDataType() ) ); if( nBand > 0 ) CPLSetXMLValue( psTree, "#band", CPLSPrintf( "%d", GetBand() ) ); psMD = oMDMD.Serialize(); if( psMD != NULL ) CPLAddXMLChild( psTree, psMD ); if( strlen(GetDescription()) > 0 ) CPLSetXMLValue( psTree, "Description", GetDescription() ); if( bNoDataValueSet ) { if (CPLIsNan(dfNoDataValue)) CPLSetXMLValue( psTree, "NoDataValue", "nan"); else CPLSetXMLValue( psTree, "NoDataValue", CPLSPrintf( "%.14E", dfNoDataValue ) ); } if( bHideNoDataValue ) CPLSetXMLValue( psTree, "HideNoDataValue", CPLSPrintf( "%d", bHideNoDataValue ) ); if( pszUnitType != NULL ) CPLSetXMLValue( psTree, "UnitType", pszUnitType ); if( dfOffset != 0.0 ) CPLSetXMLValue( psTree, "Offset", CPLSPrintf( "%.16g", dfOffset ) ); if( dfScale != 1.0 ) CPLSetXMLValue( psTree, "Scale", CPLSPrintf( "%.16g", dfScale ) ); if( eColorInterp != GCI_Undefined ) CPLSetXMLValue( psTree, "ColorInterp", GDALGetColorInterpretationName( eColorInterp ) ); /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( papszCategoryNames != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "CategoryNames" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; papszCategoryNames[iEntry] != NULL; iEntry++ ) { CPLXMLNode *psNode = CPLCreateXMLElementAndValue( NULL, "Category", papszCategoryNames[iEntry] ); if( psLastChild == NULL ) psCT_XML->psChild = psNode; else psLastChild->psNext = psNode; psLastChild = psNode; } } /* -------------------------------------------------------------------- */ /* Histograms. */ /* -------------------------------------------------------------------- */ if( psSavedHistograms != NULL ) CPLAddXMLChild( psTree, CPLCloneXMLTree( psSavedHistograms ) ); /* -------------------------------------------------------------------- */ /* Color Table. */ /* -------------------------------------------------------------------- */ if( poColorTable != NULL ) { CPLXMLNode *psCT_XML = CPLCreateXMLNode( psTree, CXT_Element, "ColorTable" ); CPLXMLNode* psLastChild = NULL; for( int iEntry=0; iEntry < poColorTable->GetColorEntryCount(); iEntry++ ) { GDALColorEntry sEntry; CPLXMLNode *psEntry_XML = CPLCreateXMLNode( NULL, CXT_Element, "Entry" ); if( psLastChild == NULL ) psCT_XML->psChild = psEntry_XML; else psLastChild->psNext = psEntry_XML; psLastChild = psEntry_XML; poColorTable->GetColorEntryAsRGB( iEntry, &sEntry ); CPLSetXMLValue( psEntry_XML, "#c1", CPLSPrintf("%d",sEntry.c1) ); CPLSetXMLValue( psEntry_XML, "#c2", CPLSPrintf("%d",sEntry.c2) ); CPLSetXMLValue( psEntry_XML, "#c3", CPLSPrintf("%d",sEntry.c3) ); CPLSetXMLValue( psEntry_XML, "#c4", CPLSPrintf("%d",sEntry.c4) ); } } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ for( int iOvr = 0; iOvr < (int)apoOverviews.size(); iOvr ++ ) { CPLXMLNode *psOVR_XML = CPLCreateXMLNode( psTree, CXT_Element, "Overview" ); int bRelativeToVRT; const char *pszRelativePath; VSIStatBufL sStat; if( VSIStatExL( apoOverviews[iOvr].osFilename, &sStat, VSI_STAT_EXISTS_FLAG ) != 0 ) { pszRelativePath = apoOverviews[iOvr].osFilename; bRelativeToVRT = FALSE; } else { pszRelativePath = CPLExtractRelativePath( pszVRTPath, apoOverviews[iOvr].osFilename, &bRelativeToVRT ); } CPLSetXMLValue( psOVR_XML, "SourceFilename", pszRelativePath ); CPLCreateXMLNode( CPLCreateXMLNode( CPLGetXMLNode( psOVR_XML, "SourceFilename" ), CXT_Attribute, "relativeToVRT" ), CXT_Text, bRelativeToVRT ? "1" : "0" ); CPLSetXMLValue( psOVR_XML, "SourceBand", CPLSPrintf("%d",apoOverviews[iOvr].nBand) ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ if( poMaskBand != NULL ) { CPLXMLNode *psBandTree = poMaskBand->SerializeToXML(pszVRTPath); if( psBandTree != NULL ) { CPLXMLNode *psMaskBandElement = CPLCreateXMLNode( psTree, CXT_Element, "MaskBand" ); CPLAddXMLChild( psMaskBandElement, psBandTree ); } } return psTree; }
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath ) { /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == NULL || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue,"VRTRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char* pszBand = CPLGetXMLValue( psTree, "band", NULL); if( pszBand != NULL ) { nBand = atoi(pszBand); } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL); if( pszDataType != NULL ) { eDataType = GDALGetDataTypeByName(pszDataType); } /* -------------------------------------------------------------------- */ /* Apply any band level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL ) SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL ) bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) ); SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) ); SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL ); SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL ) { CPLXMLNode *psEntry; CSLDestroy( papszCategoryNames ); papszCategoryNames = NULL; CPLStringList oCategoryNames; for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) ) continue; oCategoryNames.AddString( (psEntry->psChild) ? psEntry->psChild->pszValue : ""); } papszCategoryNames = oCategoryNames.StealList(); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL ) { CPLXMLNode *psEntry; GDALColorTable oTable; int iEntry = 0; for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { GDALColorEntry sCEntry; sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" )); sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" )); sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" )); sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" )); oTable.SetColorEntry( iEntry++, &sCEntry ); } SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != NULL ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = NULL; psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ CPLXMLNode *psNode; for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"Overview") ) continue; /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ char *pszSrcDSName = NULL; CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename"); const char *pszFilename = psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL; if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in Overview." ); return CE_Failure; } if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL && !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO"))) { CPLError( CE_Failure, CPLE_AppDefined, "<SourceFilename> points to a MEM dataset, which is rather suspect! " "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" ); return CE_Failure; } if( pszVRTPath != NULL && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) ) { pszSrcDSName = CPLStrdup( CPLProjectRelativeFilename( pszVRTPath, pszFilename ) ); } else pszSrcDSName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Get the raster band. */ /* -------------------------------------------------------------------- */ int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1")); apoOverviews.resize( apoOverviews.size() + 1 ); apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName; apoOverviews[apoOverviews.size()-1].nBand = nSrcBand; CPLFree( pszSrcDSName ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand"); if (psMaskBandNode) psNode = psMaskBandNode->psChild; else psNode = NULL; for( ; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"VRTRasterBand") ) continue; if( ((VRTDataset*)poDS)->poMaskBand != NULL) { CPLError( CE_Warning, CPLE_AppDefined, "Illegal mask band at raster band level when a dataset mask band already exists." ); break; } const char *pszSubclass = CPLGetXMLValue( psNode, "subclass", "VRTSourcedRasterBand" ); VRTRasterBand *poBand = NULL; if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( GetDataset(), 0 ); else { CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); break; } if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None ) { SetMaskBand(poBand); } break; } return CE_None; }
static CPLErr Resolve( CPLXMLNode * psNode, CPLXMLNode *** ppapsRoot, char *** ppapszResourceHREF, char ** papszSkip, const int bStrict ) { //for each sibling CPLXMLNode *psSibling = NULL; CPLXMLNode *psResource = NULL; CPLXMLNode *psTarget = NULL; CPLErr eReturn = CE_None, eReturned; for( psSibling = psNode; psSibling != NULL; psSibling = psSibling->psNext ) { if( psSibling->eType != CXT_Element ) continue; CPLXMLNode *psChild = psSibling->psChild; while( psChild != NULL && !( psChild->eType == CXT_Attribute && EQUAL( psChild->pszValue, "xlink:href" ) ) ) psChild = psChild->psNext; //if a child has a "xlink:href" attribute if( psChild != NULL && psChild->psChild != NULL ) { if( CSLFindString( papszSkip, psSibling->pszValue ) >= 0 ) {//Skipping a specified element eReturn = CE_Warning; continue; } static int i = 0; if( i-- == 0 ) {//a way to track progress i = 256; CPLDebug( "GML", "Resolving xlinks... (currently %s)", psChild->psChild->pszValue ); } char **papszTokens; papszTokens = CSLTokenizeString2( psChild->psChild->pszValue, "#", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if( CSLCount( papszTokens ) != 2 || strlen(papszTokens[1]) <= 0 ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_NotSupported, "Error parsing the href %s.%s", psChild->psChild->pszValue, bStrict ? "" : " Skipping..." ); CSLDestroy( papszTokens ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; continue; } //look for the resource with that URL psResource = FindTreeByURL( ppapsRoot, ppapszResourceHREF, papszTokens[0] ); if( psResource == NULL ) { CSLDestroy( papszTokens ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; continue; } //look for the element with the ID psTarget = FindElementByID( psResource, papszTokens[1] ); if( psTarget != NULL ) { //remove the xlink:href attribute CPLRemoveXMLChild( psSibling, psChild ); CPLDestroyXMLNode( psChild ); //make a copy of psTarget CPLXMLNode *psCopy = CPLCreateXMLNode( NULL, CXT_Element, psTarget->pszValue ); psCopy->psChild = CPLCloneXMLTree( psTarget->psChild ); RemoveIDs( psCopy ); //correct empty URLs in URL#id pairs if( CPLStrnlen( papszTokens[0], 1 ) > 0 ) { CorrectURLs( psCopy, papszTokens[0] ); } CPLAddXMLChild( psSibling, psCopy ); CSLDestroy( papszTokens ); } else { //element not found CSLDestroy( papszTokens ); CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_ObjectNull, "Couldn't find the element with id %s.", psChild->psChild->pszValue ); if( bStrict ) return CE_Failure; eReturn = CE_Warning; } } //Recurse with the first child eReturned=Resolve( psSibling->psChild, ppapsRoot, ppapszResourceHREF, papszSkip, bStrict ); if( eReturned == CE_Failure ) return CE_Failure; if( eReturned == CE_Warning ) eReturn = CE_Warning; } return eReturn; }
static void CPLXMLSchemaResolveInclude( const char* pszMainSchemaLocation, CPLXMLNode *psSchemaNode ) { std::set<CPLString> osAlreadyIncluded; bool bTryAgain; do { CPLXMLNode *psLast = NULL; bTryAgain = false; CPLXMLNode *psThis = psSchemaNode->psChild; for( ; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue,"include") ) { const char* pszSchemaLocation = CPLGetXMLValue(psThis, "schemaLocation", NULL); if( pszSchemaLocation != NULL && osAlreadyIncluded.count( pszSchemaLocation) == 0 ) { osAlreadyIncluded.insert( pszSchemaLocation ); if( !STARTS_WITH(pszSchemaLocation, "http://") && !STARTS_WITH(pszSchemaLocation, "https://") && CPLIsFilenameRelative(pszSchemaLocation ) ) { pszSchemaLocation = CPLFormFilename( CPLGetPath(pszMainSchemaLocation), pszSchemaLocation, NULL ); } CPLXMLNode *psIncludedXSDTree = GMLParseXMLFile( pszSchemaLocation ); if( psIncludedXSDTree != NULL ) { CPLStripXMLNamespace( psIncludedXSDTree, NULL, TRUE ); CPLXMLNode *psIncludedSchemaNode = CPLGetXMLNode( psIncludedXSDTree, "=schema" ); if( psIncludedSchemaNode != NULL ) { /* Substitute de <include> node by its content */ CPLXMLNode* psFirstChildElement = CPLGetFirstChildNode(psIncludedSchemaNode); if( psFirstChildElement != NULL ) { CPLXMLNode* psCopy = CPLCloneXMLTree(psFirstChildElement); if( psLast != NULL ) psLast->psNext = psCopy; else psSchemaNode->psChild = psCopy; CPLXMLNode* psNext = psThis->psNext; psThis->psNext = NULL; CPLDestroyXMLNode(psThis); psThis = CPLGetLastNode(psCopy); psThis->psNext = psNext; /* In case the included schema also contains */ /* includes */ bTryAgain = true; } } CPLDestroyXMLNode( psIncludedXSDTree ); } } } psLast = psThis; } } while( bTryAgain ); const char* pszSchemaOutputName = CPLGetConfigOption("GML_SCHEMA_OUTPUT_NAME", NULL); if( pszSchemaOutputName != NULL ) { CPLSerializeXMLTreeToFile( psSchemaNode, pszSchemaOutputName ); } }
CPLErr GDALPamDataset::TryLoadXML() { CPLXMLNode *psTree = NULL; PamInitialize(); /* -------------------------------------------------------------------- */ /* Clear dirty flag. Generally when we get to this point is */ /* from a call at the end of the Open() method, and some calls */ /* may have already marked the PAM info as dirty (for instance */ /* setting metadata), but really everything to this point is */ /* reproducable, and so the PAM info shouldn't really be */ /* thought of as dirty. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; /* -------------------------------------------------------------------- */ /* Try reading the file. */ /* -------------------------------------------------------------------- */ if( !BuildPamFilename() ) return CE_None; VSIStatBufL sStatBuf; if( VSIStatL( psPam->pszPamFilename, &sStatBuf ) == 0 && VSI_ISREG( sStatBuf.st_mode ) ) { CPLErrorReset(); CPLPushErrorHandler( CPLQuietErrorHandler ); psTree = CPLParseXMLFile( psPam->pszPamFilename ); CPLPopErrorHandler(); } /* -------------------------------------------------------------------- */ /* If we are looking for a subdataset, search for it's subtree */ /* now. */ /* -------------------------------------------------------------------- */ if( psTree && psPam->osSubdatasetName.size() ) { CPLXMLNode *psSubTree; for( psSubTree = psTree->psChild; psSubTree != NULL; psSubTree = psSubTree->psNext ) { if( psSubTree->eType != CXT_Element || !EQUAL(psSubTree->pszValue,"Subdataset") ) continue; if( !EQUAL(CPLGetXMLValue( psSubTree, "name", "" ), psPam->osSubdatasetName) ) continue; psSubTree = CPLGetXMLNode( psSubTree, "PAMDataset" ); break; } if( psSubTree != NULL ) psSubTree = CPLCloneXMLTree( psSubTree ); CPLDestroyXMLNode( psTree ); psTree = psSubTree; } /* -------------------------------------------------------------------- */ /* If we fail, try .aux. */ /* -------------------------------------------------------------------- */ if( psTree == NULL ) return TryLoadAux(); /* -------------------------------------------------------------------- */ /* Initialize ourselves from this XML tree. */ /* -------------------------------------------------------------------- */ CPLErr eErr; CPLString osVRTPath(CPLGetPath(psPam->pszPamFilename)); eErr = XMLInit( psTree, osVRTPath ); CPLDestroyXMLNode( psTree ); if( eErr != CE_None ) PamClear(); return eErr; }