def get_url_internal_wfs(self, ogc_server, errors): # required to do every time to validate the url. if ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH: url = self.request.route_url("mapserverproxy", _query={"ogcserver": ogc_server.name}) url_wfs = url url_internal_wfs = get_url2( "The OGC server (WFS) '{}'".format(ogc_server.name), ogc_server.url_wfs or ogc_server.url, self.request, errors=errors, ) else: url = get_url2("The OGC server '{}'".format(ogc_server.name), ogc_server.url, self.request, errors=errors) url_wfs = (get_url2( "The OGC server (WFS) '{}'".format(ogc_server.name), ogc_server.url_wfs, self.request, errors=errors, ) if ogc_server.url_wfs is not None else url) url_internal_wfs = url_wfs return url_internal_wfs, url, url_wfs
def _get_wms_url(self): ogc_server = self.ogc_server errors = set() url = get_url2("The OGC server '{}'".format(ogc_server.name), ogc_server.url, self.request, errors) if len(errors) > 0: # pragma: no cover LOG.error("\n".join(errors)) return url
def _get_wms_url(self): errors = set() url = get_url2( "The OGC server '{}'".format(self._get_ogc_server().name), self._get_ogc_server().url, self.request, errors ) if len(errors) > 0: # pragma: no cover log.error("\n".join(errors)) return url
def _get_wms_url(self): errors = set() url = get_url2( "The OGC server '{}'".format(self._get_ogc_server().name), self._get_ogc_server().url, self.request, errors ) if len(errors) > 0: # pragma: no cover log.error("\n".join(errors)) return url
def _get_wfs_url(self): ogc_server = self._get_ogc_server() errors = set() url = get_url2("The OGC server (WFS) '{}'".format(ogc_server.name), ogc_server.url_wfs or ogc_server.url, self.request, errors) if len(errors) > 0: # pragma: no cover log.error("\n".join(errors)) return url
def _themes(self, interface="desktop", filter_themes=True, min_levels=1): """ This function returns theme information for the role identified by ``role_id``. """ self._load_tree_items() errors = set() layers = self._layers(interface) themes = models.DBSession.query(main.Theme) themes = themes.filter(main.Theme.public.is_(True)) auth_themes = models.DBSession.query(main.Theme) auth_themes = auth_themes.filter(main.Theme.public.is_(False)) auth_themes = auth_themes.join(main.Theme.restricted_roles) auth_themes = auth_themes.filter( main.Role.id.in_(get_roles_id(self.request))) themes = themes.union(auth_themes) themes = themes.order_by(main.Theme.ordering.asc()) if filter_themes and interface is not None: themes = themes.join(main.Theme.interfaces) themes = themes.filter(main.Interface.name == interface) export_themes = [] for theme in themes.all(): if re.search("[/?#]", theme.name): errors.add("The theme has an unsupported name '{}'.".format( theme.name)) continue children, children_errors = self._get_children( theme, layers, min_levels) errors |= children_errors # Test if the theme is visible for the current user if children: icon = (get_url2("The Theme '{}'".format(theme.name), theme.icon, self.request, errors) if theme.icon is not None and theme.icon else self.request.static_url( "/etc/geomapfish/static/images/blank.png")) theme_theme = { "id": theme.id, "name": theme.name, "icon": icon, "children": children, "functionalities": self._get_functionalities(theme), "metadata": self._get_metadatas(theme, errors), } export_themes.append(theme_theme) return export_themes, errors
def _get_wfs_url(self): ogc_server = self.ogc_server errors: Set[str] = set() url = get_url2( "The OGC server (WFS) '{}'".format(ogc_server.name), ogc_server.url_wfs or ogc_server.url, self.request, errors, ) if errors: # pragma: no cover LOG.error("\n".join(errors)) return url
def _fill_wmts(self, layer_theme, layer, errors): layer_theme["url"] = get_url2("The WMTS layer '{}'".format(layer.name), layer.url, self.request, errors=errors) if layer.style: layer_theme["style"] = layer.style if layer.matrix_set: layer_theme["matrixSet"] = layer.matrix_set layer_theme["layer"] = layer.layer layer_theme["imageType"] = layer.image_type
def apilayers(self): try: with open('/tmp/jsapilayers.json') as json_file: data = json.load(json_file) return data except Exception as e: print("File not found") ''' View to return a list of layers. Same as the theme service but in a flat representation. ''' themes, errors = self._themes(None, None, u'main', True, 2, True) layers = {} # get themes layers for theme in themes: self._extract_layers(theme, layers) # get background layers group, errors = self._get_group(None, u'background', None, u'main', 2) self._extract_layers(group, layers, True) all_errors = set() for id in layers: url = None if 'ogcServer' in layers[id]: if 'source for' in layers[id]['ogcServer']: for ogc_server in models.DBSession.query( main.OGCServer).filter( main.OGCServer.name == layers[id] ['ogcServer']).all(): # required to do every time to validate the url. if ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH: url = self.request.route_url( "mapserverproxy", _query={"ogcserver": ogc_server.name}) else: url = get_url2("The OGC server '{}'".format( ogc_server.name), ogc_server.url, self.request, errors=all_errors) layers[id]['url'] = url try: with open('/tmp/jsapilayers.json', 'w') as json_file: json.dump(layers, json_file) except Exception as e: print(e) return layers
def test_get_url2(self): from c2cgeoportal_geoportal.lib import get_url2 request = create_dummy_request({ "package": "my_project", "servers": { "srv": "https://example.com/test", "srv_alt": "https://example.com/test/", "full_url": "https://example.com/test.xml", }, }) def static_url(path, **kwargs): del kwargs # Unused return "http://server.org/" + path request.static_url = static_url self.assertEqual( get_url2("test", "static://pr:st/icon.png", request, set()), "http://server.org/pr:st/icon.png") self.assertEqual( get_url2("test", "static:///icon.png", request, set()), "http://server.org//etc/geomapfish/static/icon.png", ) self.assertEqual( get_url2("test", "config://srv/icon.png", request, set()), "https://example.com/test/icon.png") self.assertEqual(get_url2("test", "config://srv/", request, set()), "https://example.com/test/") self.assertEqual(get_url2("test", "config://srv", request, set()), "https://example.com/test") self.assertEqual( get_url2("test", "config://srv/icon.png?test=aaa", request, set()), "https://example.com/test/icon.png?test=aaa", ) self.assertEqual( get_url2("test", "config://srv_alt/icon.png", request, set()), "https://example.com/test/icon.png") self.assertEqual(get_url2("test", "config://full_url", request, set()), "https://example.com/test.xml") self.assertEqual( get_url2("test", "http://example.com/icon.png", request, set()), "http://example.com/icon.png") self.assertEqual( get_url2("test", "https://example.com/icon.png", request, set()), "https://example.com/icon.png") errors = set() self.assertEqual( get_url2("test", "config://srv2/icon.png", request, errors=errors), None) self.assertEqual( errors, set([ "test: The server 'srv2' (config://srv2/icon.png) is not found in the config: [srv, srv_alt, full_url]" ]), )
def _layer_attributes(self, url, layer): errors = set() request = _Request() request.registry.settings = self.config # Static schema will not be supported url = get_url2("Layer", url, request, errors) if len(errors) > 0: print("\n".join(errors)) return [], [] url, headers, kwargs = self._build_url(url) if url not in self.wmscap_cache: print("Get WMS GetCapabilities for URL: {}".format(url)) self.wmscap_cache[url] = None wms_getcap_url = add_url_params( url, { "SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities", }) try: print("Get WMS GetCapabilities for URL {},\nwith headers: {}". format(wms_getcap_url, " ".join(["=".join(h) for h in headers.items()]))) response = requests.get(wms_getcap_url, headers=headers, **kwargs) try: self.wmscap_cache[url] = WebMapService( None, xml=response.content) except Exception as e: print( colorize( "ERROR! an error occurred while trying to " "parse the GetCapabilities document.", RED)) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wms_getcap_url, response.text)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print( colorize( "ERROR! Unable to GetCapabilities from URL: {},\nwith headers: {}" .format( wms_getcap_url, " ".join(["=".join(h) for h in headers.items()])), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise wmscap = self.wmscap_cache[url] if url not in self.featuretype_cache: print("Get WFS DescribeFeatureType for URL: {}".format(url)) self.featuretype_cache[url] = None wfs_descrfeat_url = add_url_params( url, { "SERVICE": "WFS", "VERSION": "1.1.0", "REQUEST": "DescribeFeatureType", }) try: response = requests.get(wfs_descrfeat_url, headers=headers, **kwargs) except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print( colorize( "ERROR! Unable to DescribeFeatureType from URL: {}". format(wfs_descrfeat_url), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [], [] else: raise if not response.ok: # pragma: no cover print( colorize( "ERROR! DescribeFeatureType from URL {} return the error: {:d} {}" .format(wfs_descrfeat_url, response.status_code, response.reason), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [], [] else: raise Exception("Aborted") try: describe = parseString(response.text) featurestype = {} self.featuretype_cache[url] = featurestype for type_element in describe.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "complexType"): featurestype[type_element.getAttribute( "name")] = type_element except ExpatError as e: print( colorize( "ERROR! an error occurred while trying to " "parse the DescribeFeatureType document.", RED)) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, response.text)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [], [] else: raise except AttributeError: print( colorize( "ERROR! an error occurred while trying to " "read the Mapfile and recover the themes.", RED)) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, response.text)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [], [] else: raise else: featurestype = self.featuretype_cache[url] if featurestype is None: return [], [] layers = [layer] if wmscap is not None and layer in list(wmscap.contents): layer_obj = wmscap[layer] if len(layer_obj.layers) > 0: layers = [l.name for l in layer_obj.layers] attributes = [] for sub_layer in layers: # Should probably be adapted for other king of servers type_element = featurestype.get("{}Type".format(sub_layer)) if type_element is not None: for element in type_element.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "element"): if not element.getAttribute("type").startswith("gml:"): attributes.append(element.getAttribute("name")) return attributes, layers
async def _wms_getcap_cached(self, ogc_server, _): """ _ is just for cache on the role id """ errors: Set[str] = set() url = get_url2("The OGC server '{}'".format(ogc_server.name), ogc_server.url, self.request, errors) if errors or url is None: # pragma: no cover return url, None, errors # Add functionality params sparams = get_mapserver_substitution_params(self.request) url = add_url_params(url, sparams) url = add_url_params( url, { "SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities", "ROLE_ID": "0", "USER_ID": "0", }, ) LOG.debug("Get WMS GetCapabilities for url: %s", url) # Forward request to target (without Host Header) headers = dict(self.request.headers) # Add headers for Geoserver if ogc_server.auth == main.OGCSERVER_AUTH_GEOSERVER: headers["sec-username"] = "******" headers["sec-roles"] = "root" if urllib.parse.urlsplit( url ).hostname != "localhost" and "Host" in headers: # pragma: no cover headers.pop("Host") try: response = await asyncio.get_event_loop().run_in_executor( None, get_http_cached, self.http_options, url, headers) except Exception: # pragma: no cover error = "Unable to GetCapabilities from URL {}".format(url) errors.add(error) LOG.error(error, exc_info=True) return url, None, errors if not response.ok: # pragma: no cover error = "GetCapabilities from URL {} return the error: {:d} {}".format( url, response.status_code, response.reason) errors.add(error) LOG.error(error) return url, None, errors # With wms 1.3 it returns text/xml also in case of error :-( if response.headers.get("Content-Type", "").split(";")[0].strip() not in [ "application/vnd.ogc.wms_xml", "text/xml", ]: error = "GetCapabilities from URL {} returns a wrong Content-Type: {}\n{}".format( url, response.headers.get("Content-Type", ""), response.text) errors.add(error) LOG.error(error) return url, None, errors return url, response.content, errors
def apilayers_full(self): ''' View to return a list of layers. Same as the theme service but in a flat representation. ''' themes, errors = self._themes(None, 1, u'main', True, 2, True) layers = {} # get themes layers for theme in themes: self._extract_layers_with_path(theme, layers, [theme['name']]) # get background layers group, errors = self._get_group(None, u'background', None, u'main', 2) self._extract_layers(group, layers, True) l = [] registry = get_current_registry() dir = registry.queryUtility(ITranslationDirectories, default=[]) localizer_fr = make_localizer("fr", dir) localizer_de = make_localizer("de", dir) localizer_en = make_localizer("en", dir) localizer_lb = make_localizer("lb", dir) client = TranslationStringFactory("geoportailv3_geoportal-client") all_errors = set() for id in layers: url = None if 'ogcServer' in layers[id]: if 'source for' in layers[id]['ogcServer']: for ogc_server in models.DBSession.query( main.OGCServer).filter( main.OGCServer.name == layers[id] ['ogcServer']).all(): # required to do every time to validate the url. if ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH: url = self.request.route_url( "mapserverproxy", _query={"ogcserver": ogc_server.name}) else: url = get_url2("The OGC server '{}'".format( ogc_server.name), ogc_server.url, self.request, errors=all_errors) entry = models.DBSession.query( main.Layer).filter(main.Layer.id == id).one() is_public = entry.public l.append({ 'id': layers[id]['id'], 'public': is_public, 'name': layers[id]['name'], 'name_fr': localizer_fr.translate(client(layers[id]['name'])), 'name_de': localizer_de.translate(client(layers[id]['name'])), 'name_en': localizer_en.translate(client(layers[id]['name'])), 'name_lb': localizer_lb.translate(client(layers[id]['name'])), 'external_url': url, 'groups': layers[id].get('came_from'), 'metadata_id': layers[id]['metadata']['metadata_id'] if 'metadata_id' in layers[id]['metadata'] else None, }) return l
def test_get_url2(self): from c2cgeoportal_geoportal.lib import get_url2 request = create_dummy_request({ "package": "my_project", "servers": { "srv": "https://example.com/test", "srv_alt": "https://example.com/test/", "full_url": "https://example.com/test.xml", }, }) def static_url(path, **kwargs): return "http://server.org/" + path request.static_url = static_url self.assertEqual(get_url2("test", "static://pr:st/icon.png", request, set()), "http://server.org/pr:st/icon.png") self.assertEqual(get_url2("test", "static:///icon.png", request, set()), "http://server.org/my_project_geoportal:static/icon.png") self.assertEqual(get_url2("test", "config://srv/icon.png", request, set()), "https://example.com/test/icon.png") self.assertEqual(get_url2("test", "config://srv/", request, set()), "https://example.com/test/") self.assertEqual(get_url2("test", "config://srv", request, set()), "https://example.com/test") self.assertEqual(get_url2("test", "config://srv/icon.png?test=aaa", request, set()), "https://example.com/test/icon.png?test=aaa") self.assertEqual(get_url2("test", "config://srv_alt/icon.png", request, set()), "https://example.com/test/icon.png") self.assertEqual(get_url2("test", "config://full_url", request, set()), "https://example.com/test.xml") self.assertEqual(get_url2("test", "http://example.com/icon.png", request, set()), "http://example.com/icon.png") self.assertEqual(get_url2("test", "https://example.com/icon.png", request, set()), "https://example.com/icon.png") errors = set() self.assertEqual(get_url2("test", "config://srv2/icon.png", request, errors=errors), None) self.assertEqual(errors, set(["The server 'srv2' is not found in the config"]))
def _layer_attributes(self, url, layer): errors = set() request = _Request() request.registry.settings = self.config # static schema will not be supported url = get_url2("Layer", url, request, errors) if len(errors) > 0: print("\n".join(errors)) return [] wms_getcap_url = add_url_params(url, { "SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities", }) hostname = urlsplit(url).hostname if url not in self.wmscap_cache: print("Get WMS GetCapabilities for URL: {}".format(url)) self.wmscap_cache[url] = None # forward request to target (without Host Header) http = httplib2.Http() h = {} if hostname == "localhost": # pragma: no cover h["Host"] = self.package["host"] try: resp, content = http.request(wms_getcap_url, method="GET", headers=h) try: self.wmscap_cache[url] = WebMapService(None, xml=content) except Exception as e: print(colorize( "ERROR! an error occurred while trying to " "parse the GetCapabilities document.", RED)) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wms_getcap_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print(colorize( "ERROR! Unable to GetCapabilities from URL: {}".format(wms_getcap_url), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise wmscap = self.wmscap_cache[url] wfs_descrfeat_url = add_url_params(url, { "SERVICE": "WFS", "VERSION": "1.1.0", "REQUEST": "DescribeFeatureType", }) if url not in self.featuretype_cache: print("Get WFS DescribeFeatureType for URL: {}".format(wfs_descrfeat_url)) self.featuretype_cache[url] = None # forward request to target (without Host Header) http = httplib2.Http() h = {} if hostname == "localhost": # pragma: no cover h["Host"] = self.package["host"] try: resp, content = http.request(wfs_descrfeat_url, method="GET", headers=h) except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print(colorize( "ERROR! Unable to DescribeFeatureType from URL: {}".format(wfs_descrfeat_url), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise if resp.status < 200 or resp.status >= 300: # pragma: no cover print(colorize( "ERROR! DescribeFeatureType from URL {} return the error: {1:d} {}".format( wfs_descrfeat_url, resp.status, resp.reason ), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise Exception("Aborted") try: describe = parseString(content) featurestype = {} self.featuretype_cache[url] = featurestype for type_element in describe.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "complexType" ): featurestype[type_element.getAttribute("name")] = type_element except ExpatError as e: print(colorize( "ERROR! an error occurred while trying to " "parse the DescribeFeatureType document.", RED )) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise except AttributeError: print(colorize( "ERROR! an error occurred while trying to " "read the Mapfile and recover the themes.", RED )) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise else: featurestype = self.featuretype_cache[url] if featurestype is None: return [] layers = [layer] if wmscap is not None and layer in list(wmscap.contents): layer_obj = wmscap[layer] if len(layer_obj.layers) > 0: layers = [l.name for l in layer_obj.layers] attributes = [] for sub_layer in layers: # Should probably be adapted for other king of servers type_element = featurestype.get("{}Type".format(sub_layer)) if type_element is not None: for element in type_element.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "element" ): if not element.getAttribute("type").startswith("gml:"): attributes.append(element.getAttribute("name")) return attributes, layers
def _layer_attributes(self, url, layer): errors = set() class Registry: setting = None class Request: registry = Registry() request = Request() request.registry.settings = self.config # static schema will not be supported url = get_url2("Layer", url, request, errors) if len(errors) > 0: print("\n".join(errors)) return [] wms_getcap_url = add_url_params(url, { "SERVICE": "WMS", "VERSION": "1.1.1", "REQUEST": "GetCapabilities", }) hostname = urlsplit(url).hostname if url not in self.wmscap_cache: print("Get WMS GetCapabilities for URL: {}".format(url)) self.wmscap_cache[url] = None # forward request to target (without Host Header) http = httplib2.Http() h = {} if hostname == "localhost": # pragma: no cover h["Host"] = self.package["host"] try: resp, content = http.request(wms_getcap_url, method="GET", headers=h) try: self.wmscap_cache[url] = WebMapService(None, xml=content) except Exception as e: print( colorize( "ERROR! an error occurred while trying to " "parse the GetCapabilities document.", RED)) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wms_getcap_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print( colorize( "ERROR! Unable to GetCapabilities from URL: {}".format( wms_getcap_url), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") != "TRUE": raise wmscap = self.wmscap_cache[url] wfs_descrfeat_url = add_url_params( url, { "SERVICE": "WFS", "VERSION": "1.1.0", "REQUEST": "DescribeFeatureType", }) if url not in self.featuretype_cache: print("Get WFS DescribeFeatureType for URL: {}".format( wfs_descrfeat_url)) self.featuretype_cache[url] = None # forward request to target (without Host Header) http = httplib2.Http() h = {} if hostname == "localhost": # pragma: no cover h["Host"] = self.package["host"] try: resp, content = http.request(wfs_descrfeat_url, method="GET", headers=h) except Exception as e: # pragma: no cover print(colorize(str(e), RED)) print( colorize( "ERROR! Unable to DescribeFeatureType from URL: {}". format(wfs_descrfeat_url), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise if resp.status < 200 or resp.status >= 300: # pragma: no cover print( colorize( "ERROR! DescribeFeatureType from URL {} return the error: {1:d} {}" .format(wfs_descrfeat_url, resp.status, resp.reason), RED, )) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise Exception("Aborted") try: describe = parseString(content) featurestype = {} self.featuretype_cache[url] = featurestype for type_element in describe.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "complexType"): featurestype[type_element.getAttribute( "name")] = type_element except ExpatError as e: print( colorize( "ERROR! an error occurred while trying to " "parse the DescribeFeatureType document.", RED)) print(colorize(str(e), RED)) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise except AttributeError: print( colorize( "ERROR! an error occurred while trying to " "read the Mapfile and recover the themes.", RED)) print("URL: {}\nxml:\n{}".format(wfs_descrfeat_url, content)) if os.environ.get("IGNORE_I18N_ERRORS", "FALSE") == "TRUE": return [] else: raise else: featurestype = self.featuretype_cache[url] if featurestype is None: return [] layers = [layer] if wmscap is not None and layer in list(wmscap.contents): layer_obj = wmscap[layer] if len(layer_obj.layers) > 0: layers = [l.name for l in layer_obj.layers] attributes = [] for sub_layer in layers: # Should probably be adapted for other king of servers type_element = featurestype.get("{}Type".format(sub_layer)) if type_element is not None: for element in type_element.getElementsByTagNameNS( "http://www.w3.org/2001/XMLSchema", "element"): if not element.getAttribute("type").startswith("gml:"): attributes.append(element.getAttribute("name")) return attributes