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 109 : bool GMLRegistry::Parse() 29 : { 30 : #ifndef USE_ONLY_EMBEDDED_RESOURCE_FILES 31 109 : if (osRegistryPath.empty()) 32 : { 33 : #ifdef EMBED_RESOURCE_FILES 34 : CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler); 35 : #endif 36 108 : const char *pszFilename = CPLFindFile("gdal", "gml_registry.xml"); 37 108 : if (pszFilename) 38 108 : osRegistryPath = pszFilename; 39 : } 40 : #endif 41 109 : CPLXMLNode *psRootNode = nullptr; 42 109 : if (!osRegistryPath.empty()) 43 : { 44 109 : 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 109 : if (psRootNode == nullptr) 62 0 : return false; 63 109 : CPLXMLNode *psRegistryNode = CPLGetXMLNode(psRootNode, "=gml_registry"); 64 109 : if (psRegistryNode == nullptr) 65 : { 66 0 : CPLDestroyXMLNode(psRootNode); 67 0 : return false; 68 : } 69 109 : CPLXMLNode *psIter = psRegistryNode->psChild; 70 1298 : while (psIter != nullptr) 71 : { 72 1189 : if (psIter->eType == CXT_Element && 73 649 : strcmp(psIter->pszValue, "namespace") == 0) 74 : { 75 1298 : GMLRegistryNamespace oNameSpace; 76 649 : if (oNameSpace.Parse(osRegistryPath, psIter)) 77 : { 78 649 : aoNamespaces.push_back(oNameSpace); 79 : } 80 : } 81 1189 : psIter = psIter->psNext; 82 : } 83 109 : CPLDestroyXMLNode(psRootNode); 84 109 : return true; 85 : } 86 : 87 : /************************************************************************/ 88 : /* Parse() */ 89 : /************************************************************************/ 90 : 91 649 : bool GMLRegistryNamespace::Parse(const char *pszRegistryFilename, 92 : CPLXMLNode *psNode) 93 : { 94 649 : const char *pszPrefix = CPLGetXMLValue(psNode, "prefix", ""); 95 649 : const char *pszURI = CPLGetXMLValue(psNode, "uri", nullptr); 96 649 : if (pszURI == nullptr) 97 0 : return false; 98 649 : osPrefix = pszPrefix; 99 649 : osURI = pszURI; 100 : const char *pszUseGlobalSRSName = 101 649 : CPLGetXMLValue(psNode, "useGlobalSRSName", nullptr); 102 649 : if (pszUseGlobalSRSName != nullptr && 103 541 : strcmp(pszUseGlobalSRSName, "true") == 0) 104 541 : bUseGlobalSRSName = true; 105 : 106 649 : CPLXMLNode *psIter = psNode->psChild; 107 7025 : while (psIter != nullptr) 108 : { 109 6376 : if (psIter->eType == CXT_Element && 110 4645 : strcmp(psIter->pszValue, "featureType") == 0) 111 : { 112 9290 : GMLRegistryFeatureType oFeatureType; 113 4645 : if (oFeatureType.Parse(pszRegistryFilename, psIter)) 114 : { 115 4645 : aoFeatureTypes.push_back(oFeatureType); 116 : } 117 : } 118 6376 : psIter = psIter->psNext; 119 : } 120 649 : return true; 121 : } 122 : 123 : /************************************************************************/ 124 : /* Parse() */ 125 : /************************************************************************/ 126 : 127 4645 : bool GMLRegistryFeatureType::Parse(const char *pszRegistryFilename, 128 : CPLXMLNode *psNode) 129 : { 130 4645 : const char *pszElementName = CPLGetXMLValue(psNode, "elementName", nullptr); 131 4645 : osSchemaLocation = CPLGetXMLValue(psNode, "schemaLocation", ""); 132 4645 : osGFSSchemaLocation = CPLGetXMLValue(psNode, "gfsSchemaLocation", ""); 133 13502 : if (pszElementName == nullptr || 134 8857 : (osSchemaLocation.empty() && osGFSSchemaLocation.empty())) 135 0 : return false; 136 : 137 : const char *pszElementValue = 138 4645 : CPLGetXMLValue(psNode, "elementValue", nullptr); 139 4645 : osElementName = pszElementName; 140 : 141 4645 : if (!osSchemaLocation.empty()) 142 : { 143 1299 : if (pszRegistryFilename[0] && 144 433 : !STARTS_WITH(osSchemaLocation.c_str(), "http://") && 145 867 : !STARTS_WITH(osSchemaLocation.c_str(), "https://") && 146 1 : CPLIsFilenameRelative(osSchemaLocation.c_str())) 147 : { 148 : osSchemaLocation = 149 2 : CPLFormFilenameSafe(CPLGetPathSafe(pszRegistryFilename).c_str(), 150 1 : osSchemaLocation.c_str(), nullptr); 151 : } 152 : } 153 4212 : else if (!osGFSSchemaLocation.empty()) 154 : { 155 12636 : if (pszRegistryFilename[0] && 156 4212 : !STARTS_WITH(osGFSSchemaLocation.c_str(), "http://") && 157 12636 : !STARTS_WITH(osGFSSchemaLocation.c_str(), "https://") && 158 4212 : CPLIsFilenameRelative(osGFSSchemaLocation.c_str())) 159 : { 160 : osGFSSchemaLocation = 161 8424 : CPLFormFilenameSafe(CPLGetPathSafe(pszRegistryFilename).c_str(), 162 4212 : osGFSSchemaLocation.c_str(), nullptr); 163 : } 164 : } 165 : 166 4645 : if (pszElementValue != nullptr) 167 : { 168 432 : osElementValue = pszElementValue; 169 : } 170 : 171 4645 : return true; 172 : }