Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GML registry 4 : * Purpose: GML reader 5 : * Author: Even Rouault, <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "cpl_port.h" 14 : #include "gmlregistry.h" 15 : 16 : #include <cstring> 17 : 18 : #include "cpl_conv.h" 19 : 20 : #ifdef EMBED_RESOURCE_FILES 21 : #include "embedded_resources.h" 22 : #endif 23 : 24 : /************************************************************************/ 25 : /* Parse() */ 26 : /************************************************************************/ 27 : 28 101 : bool GMLRegistry::Parse() 29 : { 30 : #ifndef USE_ONLY_EMBEDDED_RESOURCE_FILES 31 101 : if (osRegistryPath.empty()) 32 : { 33 : #ifdef EMBED_RESOURCE_FILES 34 : CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler); 35 : #endif 36 100 : const char *pszFilename = CPLFindFile("gdal", "gml_registry.xml"); 37 100 : if (pszFilename) 38 100 : osRegistryPath = pszFilename; 39 : } 40 : #endif 41 101 : CPLXMLNode *psRootNode = nullptr; 42 101 : if (!osRegistryPath.empty()) 43 : { 44 101 : psRootNode = CPLParseXMLFile(osRegistryPath); 45 : } 46 : #ifdef EMBED_RESOURCE_FILES 47 : else 48 : { 49 : const char *pszContent = GMLGetFileContent("gml_registry.xml"); 50 : if (pszContent) 51 : { 52 : static const bool bOnce [[maybe_unused]] = []() 53 : { 54 : CPLDebug("GML", "Using embedded gml_registry.xml"); 55 : return true; 56 : }(); 57 : psRootNode = CPLParseXMLString(pszContent); 58 : } 59 : } 60 : #endif 61 101 : if (psRootNode == nullptr) 62 0 : return false; 63 101 : CPLXMLNode *psRegistryNode = CPLGetXMLNode(psRootNode, "=gml_registry"); 64 101 : if (psRegistryNode == nullptr) 65 : { 66 0 : CPLDestroyXMLNode(psRootNode); 67 0 : return false; 68 : } 69 101 : CPLXMLNode *psIter = psRegistryNode->psChild; 70 1202 : while (psIter != nullptr) 71 : { 72 1101 : if (psIter->eType == CXT_Element && 73 601 : strcmp(psIter->pszValue, "namespace") == 0) 74 : { 75 1202 : GMLRegistryNamespace oNameSpace; 76 601 : if (oNameSpace.Parse(osRegistryPath, psIter)) 77 : { 78 601 : aoNamespaces.push_back(oNameSpace); 79 : } 80 : } 81 1101 : psIter = psIter->psNext; 82 : } 83 101 : CPLDestroyXMLNode(psRootNode); 84 101 : return true; 85 : } 86 : 87 : /************************************************************************/ 88 : /* Parse() */ 89 : /************************************************************************/ 90 : 91 601 : bool GMLRegistryNamespace::Parse(const char *pszRegistryFilename, 92 : CPLXMLNode *psNode) 93 : { 94 601 : const char *pszPrefix = CPLGetXMLValue(psNode, "prefix", ""); 95 601 : const char *pszURI = CPLGetXMLValue(psNode, "uri", nullptr); 96 601 : if (pszURI == nullptr) 97 0 : return false; 98 601 : osPrefix = pszPrefix; 99 601 : osURI = pszURI; 100 : const char *pszUseGlobalSRSName = 101 601 : CPLGetXMLValue(psNode, "useGlobalSRSName", nullptr); 102 601 : if (pszUseGlobalSRSName != nullptr && 103 501 : strcmp(pszUseGlobalSRSName, "true") == 0) 104 501 : bUseGlobalSRSName = true; 105 : 106 601 : CPLXMLNode *psIter = psNode->psChild; 107 6505 : while (psIter != nullptr) 108 : { 109 5904 : if (psIter->eType == CXT_Element && 110 4301 : strcmp(psIter->pszValue, "featureType") == 0) 111 : { 112 8602 : GMLRegistryFeatureType oFeatureType; 113 4301 : if (oFeatureType.Parse(pszRegistryFilename, psIter)) 114 : { 115 4301 : aoFeatureTypes.push_back(oFeatureType); 116 : } 117 : } 118 5904 : psIter = psIter->psNext; 119 : } 120 601 : return true; 121 : } 122 : 123 : /************************************************************************/ 124 : /* Parse() */ 125 : /************************************************************************/ 126 : 127 4301 : bool GMLRegistryFeatureType::Parse(const char *pszRegistryFilename, 128 : CPLXMLNode *psNode) 129 : { 130 4301 : const char *pszElementName = CPLGetXMLValue(psNode, "elementName", nullptr); 131 : const char *pszSchemaLocation = 132 4301 : CPLGetXMLValue(psNode, "schemaLocation", nullptr); 133 : const char *pszGFSSchemaLocation = 134 4301 : CPLGetXMLValue(psNode, "gfsSchemaLocation", nullptr); 135 4301 : if (pszElementName == nullptr || 136 3900 : (pszSchemaLocation == nullptr && pszGFSSchemaLocation == nullptr)) 137 0 : return false; 138 : 139 : const char *pszElementValue = 140 4301 : CPLGetXMLValue(psNode, "elementValue", nullptr); 141 4301 : osElementName = pszElementName; 142 : 143 4301 : if (pszSchemaLocation != nullptr) 144 : { 145 1203 : if (pszRegistryFilename[0] && 146 401 : !STARTS_WITH(pszSchemaLocation, "http://") && 147 803 : !STARTS_WITH(pszSchemaLocation, "https://") && 148 1 : CPLIsFilenameRelative(pszSchemaLocation)) 149 : { 150 1 : pszSchemaLocation = CPLFormFilename(CPLGetPath(pszRegistryFilename), 151 : pszSchemaLocation, nullptr); 152 : } 153 401 : osSchemaLocation = pszSchemaLocation; 154 : } 155 3900 : else if (pszGFSSchemaLocation != nullptr) 156 : { 157 11700 : if (pszRegistryFilename[0] && 158 3900 : !STARTS_WITH(pszGFSSchemaLocation, "http://") && 159 11700 : !STARTS_WITH(pszGFSSchemaLocation, "https://") && 160 3900 : CPLIsFilenameRelative(pszGFSSchemaLocation)) 161 : { 162 3900 : pszGFSSchemaLocation = CPLFormFilename( 163 : CPLGetPath(pszRegistryFilename), pszGFSSchemaLocation, nullptr); 164 : } 165 3900 : osGFSSchemaLocation = pszGFSSchemaLocation; 166 : } 167 : 168 4301 : if (pszElementValue != nullptr) 169 : { 170 400 : osElementValue = pszElementValue; 171 : } 172 : 173 4301 : return true; 174 : }