/src/gdal/ogr/ogrsf_frmts/gml/gmlregistry.cpp
Line | Count | Source |
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 | | bool GMLRegistry::Parse() |
29 | 2.68k | { |
30 | 2.68k | #ifndef USE_ONLY_EMBEDDED_RESOURCE_FILES |
31 | 2.68k | if (osRegistryPath.empty()) |
32 | 2.68k | { |
33 | 2.68k | #ifdef EMBED_RESOURCE_FILES |
34 | 2.68k | CPLErrorStateBackuper oErrorStateBackuper(CPLQuietErrorHandler); |
35 | 2.68k | #endif |
36 | 2.68k | const char *pszFilename = CPLFindFile("gdal", "gml_registry.xml"); |
37 | 2.68k | if (pszFilename) |
38 | 0 | osRegistryPath = pszFilename; |
39 | 2.68k | } |
40 | 2.68k | #endif |
41 | 2.68k | CPLXMLNode *psRootNode = nullptr; |
42 | 2.68k | if (!osRegistryPath.empty()) |
43 | 0 | { |
44 | 0 | psRootNode = CPLParseXMLFile(osRegistryPath); |
45 | 0 | } |
46 | 2.68k | #ifdef EMBED_RESOURCE_FILES |
47 | 2.68k | else |
48 | 2.68k | { |
49 | 2.68k | const char *pszContent = GMLGetFileContent("gml_registry.xml"); |
50 | 2.68k | if (pszContent) |
51 | 2.68k | { |
52 | 2.68k | static const bool bOnce [[maybe_unused]] = []() |
53 | 2.68k | { |
54 | 6 | CPLDebug("GML", "Using embedded gml_registry.xml"); |
55 | 6 | return true; |
56 | 6 | }(); |
57 | 2.68k | psRootNode = CPLParseXMLString(pszContent); |
58 | 2.68k | } |
59 | 2.68k | } |
60 | 2.68k | #endif |
61 | 2.68k | if (psRootNode == nullptr) |
62 | 0 | return false; |
63 | 2.68k | CPLXMLNode *psRegistryNode = CPLGetXMLNode(psRootNode, "=gml_registry"); |
64 | 2.68k | if (psRegistryNode == nullptr) |
65 | 0 | { |
66 | 0 | CPLDestroyXMLNode(psRootNode); |
67 | 0 | return false; |
68 | 0 | } |
69 | 2.68k | CPLXMLNode *psIter = psRegistryNode->psChild; |
70 | 32.1k | while (psIter != nullptr) |
71 | 29.5k | { |
72 | 29.5k | if (psIter->eType == CXT_Element && |
73 | 16.0k | strcmp(psIter->pszValue, "namespace") == 0) |
74 | 16.0k | { |
75 | 16.0k | GMLRegistryNamespace oNameSpace; |
76 | 16.0k | if (oNameSpace.Parse(osRegistryPath, psIter)) |
77 | 16.0k | { |
78 | 16.0k | aoNamespaces.push_back(std::move(oNameSpace)); |
79 | 16.0k | } |
80 | 16.0k | } |
81 | 29.5k | psIter = psIter->psNext; |
82 | 29.5k | } |
83 | 2.68k | CPLDestroyXMLNode(psRootNode); |
84 | 2.68k | return true; |
85 | 2.68k | } |
86 | | |
87 | | /************************************************************************/ |
88 | | /* Parse() */ |
89 | | /************************************************************************/ |
90 | | |
91 | | bool GMLRegistryNamespace::Parse(const char *pszRegistryFilename, |
92 | | CPLXMLNode *psNode) |
93 | 16.0k | { |
94 | 16.0k | const char *pszPrefix = CPLGetXMLValue(psNode, "prefix", ""); |
95 | 16.0k | const char *pszURI = CPLGetXMLValue(psNode, "uri", nullptr); |
96 | 16.0k | if (pszURI == nullptr) |
97 | 0 | return false; |
98 | 16.0k | osPrefix = pszPrefix; |
99 | 16.0k | osURI = pszURI; |
100 | 16.0k | const char *pszUseGlobalSRSName = |
101 | 16.0k | CPLGetXMLValue(psNode, "useGlobalSRSName", nullptr); |
102 | 16.0k | if (pszUseGlobalSRSName != nullptr && |
103 | 13.4k | strcmp(pszUseGlobalSRSName, "true") == 0) |
104 | 13.4k | bUseGlobalSRSName = true; |
105 | | |
106 | 16.0k | CPLXMLNode *psIter = psNode->psChild; |
107 | 174k | while (psIter != nullptr) |
108 | 158k | { |
109 | 158k | if (psIter->eType == CXT_Element && |
110 | 115k | strcmp(psIter->pszValue, "featureType") == 0) |
111 | 115k | { |
112 | 115k | GMLRegistryFeatureType oFeatureType; |
113 | 115k | if (oFeatureType.Parse(pszRegistryFilename, psIter)) |
114 | 115k | { |
115 | 115k | aoFeatureTypes.push_back(std::move(oFeatureType)); |
116 | 115k | } |
117 | 115k | } |
118 | 158k | psIter = psIter->psNext; |
119 | 158k | } |
120 | 16.0k | return true; |
121 | 16.0k | } |
122 | | |
123 | | /************************************************************************/ |
124 | | /* Parse() */ |
125 | | /************************************************************************/ |
126 | | |
127 | | bool GMLRegistryFeatureType::Parse(const char *pszRegistryFilename, |
128 | | CPLXMLNode *psNode) |
129 | 115k | { |
130 | 115k | const char *pszElementName = CPLGetXMLValue(psNode, "elementName", nullptr); |
131 | 115k | osSchemaLocation = CPLGetXMLValue(psNode, "schemaLocation", ""); |
132 | 115k | osGFSSchemaLocation = CPLGetXMLValue(psNode, "gfsSchemaLocation", ""); |
133 | 115k | if (pszElementName == nullptr || |
134 | 115k | (osSchemaLocation.empty() && osGFSSchemaLocation.empty())) |
135 | 0 | return false; |
136 | | |
137 | 115k | const char *pszElementValue = |
138 | 115k | CPLGetXMLValue(psNode, "elementValue", nullptr); |
139 | 115k | osElementName = pszElementName; |
140 | | |
141 | 115k | if (!osSchemaLocation.empty()) |
142 | 10.7k | { |
143 | 10.7k | if (pszRegistryFilename[0] && |
144 | 0 | !STARTS_WITH(osSchemaLocation.c_str(), "http://") && |
145 | 0 | !STARTS_WITH(osSchemaLocation.c_str(), "https://") && |
146 | 0 | CPLIsFilenameRelative(osSchemaLocation.c_str())) |
147 | 0 | { |
148 | 0 | osSchemaLocation = |
149 | 0 | CPLFormFilenameSafe(CPLGetPathSafe(pszRegistryFilename).c_str(), |
150 | 0 | osSchemaLocation.c_str(), nullptr); |
151 | 0 | } |
152 | 10.7k | } |
153 | 104k | else if (!osGFSSchemaLocation.empty()) |
154 | 104k | { |
155 | 104k | if (pszRegistryFilename[0] && |
156 | 0 | !STARTS_WITH(osGFSSchemaLocation.c_str(), "http://") && |
157 | 0 | !STARTS_WITH(osGFSSchemaLocation.c_str(), "https://") && |
158 | 0 | CPLIsFilenameRelative(osGFSSchemaLocation.c_str())) |
159 | 0 | { |
160 | 0 | osGFSSchemaLocation = |
161 | 0 | CPLFormFilenameSafe(CPLGetPathSafe(pszRegistryFilename).c_str(), |
162 | 0 | osGFSSchemaLocation.c_str(), nullptr); |
163 | 0 | } |
164 | 104k | } |
165 | | |
166 | 115k | if (pszElementValue != nullptr) |
167 | 10.7k | { |
168 | 10.7k | osElementValue = pszElementValue; |
169 | 10.7k | } |
170 | | |
171 | 115k | return true; |
172 | 115k | } |