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