{ "info": { "author": "", "author_email": "", "bugtrack_url": null, "classifiers": [], "description": "# gis_metadata_parser\n\nXML parsers for GIS metadata that are designed to read in, validate, update and output a core set of properties that have been mapped between the most common standards, currently:\n\n* FGDC\n* ISO-19139 (and ISO-19115)\n* ArcGIS (tested with ArcGIS format 1.0).\n\nThis library is compatible with Python versions 2.7 and 3.4 through 3.6.\n\n[![Build Status](https://travis-ci.org/consbio/gis-metadata-parser.png?branch=master)](https://travis-ci.org/consbio/gis-metadata-parser) [![Coverage Status](https://coveralls.io/repos/github/consbio/gis-metadata-parser/badge.svg?branch=master)](https://coveralls.io/github/consbio/gis-metadata-parser?branch=master)\n\n## Installation\nInstall with `pip install gis-metadata-parser`.\n\n## Usage\n\nParsers can be instantiated from files, XML strings or URLs. They can be converted from one standard to another as well.\n```python\nfrom gis_metadata.arcgis_metadata_parser import ArcGISParser\nfrom gis_metadata.fgdc_metadata_parser import FgdcParser\nfrom gis_metadata.iso_metadata_parser import IsoParser\nfrom gis_metadata.metadata_parser import get_metadata_parser\n\n# From file objects\nwith open(r'/path/to/metadata.xml') as metadata:\n fgdc_from_file = FgdcParser(metadata)\n\nwith open(r'/path/to/metadata.xml') as metadata:\n iso_from_file = IsoParser(metadata)\n\n# Detect standard based on root element, metadata\nfgdc_from_string = get_metadata_parser(\n \"\"\"\n \n \n \n \n \n \"\"\"\n)\n\n# Detect ArcGIS standard based on root element and its nodes\niso_from_string = get_metadata_parser(\n \"\"\"\n \n \n \n \n \n \n \"\"\"\n)\n\n# Detect ISO standard based on root element, MD_Metadata or MI_Metadata\niso_from_string = get_metadata_parser(\n \"\"\"\n \n \n \n \n \n \"\"\"\n)\n\n# Convert from one standard to another\nfgdc_converted = iso_from_file.convert_to(FgdcParser)\niso_converted = fgdc_from_file.convert_to(IsoParser)\narcgis_converted = iso_converted.convert_to(ArcGISParser)\n```\n\nFinally, the properties of the parser can be updated, validated, applied and output:\n```python\nwith open(r'/path/to/metadata.xml') as metadata:\n fgdc_from_file = FgdcParser(metadata)\n\n# Example simple properties\nfgdc_from_file.title\nfgdc_from_file.abstract\nfgdc_from_file.place_keywords\nfgdc_from_file.thematic_keywords\n\n# :see: gis_metadata.utils.get_supported_props for list of all supported properties\n\n# Complex properties\nfgdc_from_file.attributes\nfgdc_from_file.bounding_box\nfgdc_from_file.contacts\nfgdc_from_file.dates\nfgdc_from_file.digital_forms\nfgdc_from_file.larger_works\nfgdc_from_file.process_steps\nfgdc_from_file.raster_info\n\n# :see: gis_metadata.utils.get_complex_definitions for structure of all complex properties\n\n# Update properties\nfgdc_from_file.title = 'New Title'\nfgdc_from_file.dates = {'type': 'single' 'values': '1/1/2016'}\n\n# Apply updates\nfgdc_from_file.validate() # Ensure updated properties are valid\nfgdc_from_file.serialize() # Output updated XML as a string\nfgdc_from_file.write() # Output updated XML to existing file\nfgdc_from_file.write(out_file_or_path='/path/to/updated.xml') # Output updated XML to new file\n```\n\n## Extending and Customizing\n\n### Tips\n\nThere are a few unwritten (until now) rules about the way the metadata parsers are wired to work:\n\n1. Properties are generally defined by XPATH in each `parser._data_map`\n2. Simple parser properties accept only values of `string` and `list`'s of `string`'s\n3. XPATH's configured in the data map support references to element attributes: `'path/to/element/@attr'`\n4. Complex parser properties are defined by custom parser/updater functions instead of by XPATH\n5. Complex parser properties accept values of type `dict` containing simple properties, or a list of said `dict`'s\n6. Properties with leading underscores are parsed, but not validated or written out\n7. Properties that \"shadow\" other properties but with a leading underscore serve as backup values\n8. For backup properties, additional underscores indicate further backup options, i.e. `title`, `_title`, `__title`\n\nSome examples of existing backup properties are as follows:\n```python\n# In the ArcGIS parser for distribution contact phone:\n\n_agis_tag_formats = {\n ...\n 'dist_phone': 'distInfo/distributor/distorCont/rpCntInfo/cntPhone/voiceNum',\n '_dist_phone': 'distInfo/distributor/distorCont/rpCntInfo/voiceNum', # If not in cntPhone\n ...\n}\n\n# In the FGDC parser for sub-properties in the contacts definition:\n\n_fgdc_definitions = get_complex_definitions()\n_fgdc_definitions[CONTACTS].update({\n '_name': '{_name}',\n '_organization': '{_organization}'\n})\n...\nclass FgdcParser(MetadataParser):\n ...\n def _init_data_map(self):\n ...\n ct_format = _fgdc_tag_formats[CONTACTS]\n fgdc_data_structures[CONTACTS] = format_xpaths(\n ...\n name=ct_format.format(ct_path='cntperp/cntper'),\n _name=ct_format.format(ct_path='cntorgp/cntper'), # If not in cntperp\n organization=ct_format.format(ct_path='cntperp/cntorg'),\n _organization=ct_format.format(ct_path='cntorgp/cntorg'), # If not in cntperp\n )\n\n# Also see the ISO parser for backup sub-properties in the attributes definition:\n\n_iso_definitions = get_complex_definitions()\n_iso_definitions[ATTRIBUTES].update({\n '_definition_source': '{_definition_src}',\n '__definition_source': '{__definition_src}',\n '___definition_source': '{___definition_src}'\n})\n\n```\n\n\n### Examples\n\nAny of the supported parsers can be extended to include more of a standard's supported data. In this example we'll add two new properties to the `IsoParser`:\n\n* `metadata_language`: a simple string field describing the language of the metadata file itself (not the dataset)\n* `metadata_contacts`: a complex structure with contact info leveraging and enhancing the existing contact structure\n\nThis example will cover:\n\n1. Adding a new simple property\n2. Configuring a backup location for a property\n3. Referencing an element attribute in an XPATH\n4. Adding a new complex property\n5. Customizing the complex property to include a new sub-property\n\nAlso, this example is specifically covered by unit tests.\n\n```python\nfrom gis_metadata.iso_metadata_parser import IsoParser\nfrom gis_metadata.utils import CONTACTS, format_xpaths, get_complex_definitions, ParserProperty\n\n\nclass CustomIsoParser(IsoParser):\n\n def _init_data_map(self):\n super(CustomIsoParser, self)._init_data_map()\n\n # Basic property: text or list (with backup location referencing codeListValue attribute)\n\n lang_prop = 'metadata_language'\n self._data_map[lang_prop] = 'language/CharacterString' # Parse from here if present\n self._data_map['_' + lang_prop] = 'language/LanguageCode/@codeListValue' # Otherwise, try from here\n\n # Complex structure (reuse of contacts structure plus phone)\n\n # Define some basic variables\n ct_prop = 'metadata_contacts'\n ct_xpath = 'contact/CI_ResponsibleParty/{ct_path}'\n ct_defintion = get_complex_definitions()[CONTACTS]\n ct_defintion['phone'] = '{phone}'\n\n # Reuse CONTACT structure to specify locations per prop (adapted only slightly from parent)\n self._data_structures[ct_prop] = format_xpaths(\n ct_defintion,\n name=ct_xpath.format(ct_path='individualName/CharacterString'),\n organization=ct_xpath.format(ct_path='organisationName/CharacterString'),\n position=ct_xpath.format(ct_path='positionName/CharacterString'),\n phone=ct_xpath.format(\n ct_path='contactInfo/CI_Contact/phone/CI_Telephone/voice/CharacterString'\n ),\n email=ct_xpath.format(\n ct_path='contactInfo/CI_Contact/address/CI_Address/electronicMailAddress/CharacterString'\n )\n )\n\n # Set the contact root to insert new elements at \"contact\" level given the defined path:\n # 'contact/CI_ResponsibleParty/...'\n # By default we would get multiple \"CI_ResponsibleParty\" elements under a single \"contact\"\n # This way we get multiple \"contact\" elements, each with its own single \"CI_ResponsibleParty\"\n self._data_map['_{prop}_root'.format(prop=ct_prop)] = 'contact'\n\n # Use the built-in support for parsing complex properties (or write your own a parser/updater)\n self._data_map[ct_prop] = ParserProperty(self._parse_complex_list, self._update_complex_list)\n\n # And finally, let the parent validation logic know about the two new custom properties\n\n self._metadata_props.add(lang_prop)\n self._metadata_props.add(ct_prop)\n\n\nwith open(r'/path/to/metadata.xml') as metadata:\n iso_from_file = CustomIsoParser(metadata)\n\niso_from_file.metadata_language\niso_from_file.metadata_contacts\n```\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/consbio/gis-metadata-parser", "keywords": "arcgis,fgdc,iso,ISO-19115,ISO-19139,gis,metadata,parser,xml,gis_metadata,gis_metadata_parser", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "gis-metadata-parser", "package_url": "https://pypi.org/project/gis-metadata-parser/", "platform": "", "project_url": "https://pypi.org/project/gis-metadata-parser/", "project_urls": { "Homepage": "https://github.com/consbio/gis-metadata-parser" }, "release_url": "https://pypi.org/project/gis-metadata-parser/1.1.4/", "requires_dist": [ "parserutils (>=1.1)", "six (>=1.9.0)" ], "requires_python": "", "summary": "Parser for GIS metadata standards including FGDC and ISO-19115", "version": "1.1.4" }, "last_serial": 4024064, "releases": { "0.9.7": [ { "comment_text": "", "digests": { "md5": "e2fbeadad07bebc5f251298892c1590e", "sha256": "47cf22244b312dbc6bb3f37477574452f9e515cacffaa35f1d7c0f4ec511b2cd" }, "downloads": -1, "filename": "gis_metadata_parser-0.9.7-py3-none-any.whl", "has_sig": false, "md5_digest": "e2fbeadad07bebc5f251298892c1590e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 36515, "upload_time": "2016-12-20T23:12:34", "url": "https://files.pythonhosted.org/packages/18/01/52b601f8d673753222ef6d7e012ca3da561a8abeebc29b6cffbb9a29c7a2/gis_metadata_parser-0.9.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5fdca838ae391e64a5806f018e3d7e0e", "sha256": "4169e66aa43ed53bc8f093bf37dddab3a4f709e9108f4ed67d7c3e6d2453ebca" }, "downloads": -1, "filename": "gis_metadata_parser-0.9.7.tar.gz", "has_sig": false, "md5_digest": "5fdca838ae391e64a5806f018e3d7e0e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29738, "upload_time": "2016-12-20T23:12:36", "url": "https://files.pythonhosted.org/packages/81/76/cf837c667187a356a4c0ed9e59182d61a783f7b093379b28c2970c96979e/gis_metadata_parser-0.9.7.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "4f93e8c050abbf86e988ccec98ac8257", "sha256": "52a0ec1f0c51ca02db10f9228de4eb2dd6d3bd841ba5e2e4121c61b771364c62" }, "downloads": -1, "filename": "gis_metadata_parser-1.0-py3.6.egg", "has_sig": false, "md5_digest": "4f93e8c050abbf86e988ccec98ac8257", "packagetype": "bdist_egg", "python_version": "3.6", "requires_python": null, "size": 87281, "upload_time": "2018-06-02T00:16:55", "url": "https://files.pythonhosted.org/packages/21/b5/fabc20735c176742e5c683e19e7b3cec2167e010bb2f82e882b45603272f/gis_metadata_parser-1.0-py3.6.egg" }, { "comment_text": "", "digests": { "md5": "3cbf1ab67cc17c324bb43144c404166e", "sha256": "d266cc3be6c445717409e967e7ff381cf1246571a9cdf2503193970291595304" }, "downloads": -1, "filename": "gis_metadata_parser-1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "3cbf1ab67cc17c324bb43144c404166e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 38992, "upload_time": "2017-07-31T22:28:53", "url": "https://files.pythonhosted.org/packages/36/aa/706082415be2048e75f0abe2a4735f0340958d8acce627a52bd782551380/gis_metadata_parser-1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f2c912d3885c7ced082b4c4ef7fe8fb0", "sha256": "ad54d06cb097652df8072c792932e392bf6b57c618b8dcfa9aeef7adb7ad72b7" }, "downloads": -1, "filename": "gis_metadata_parser-1.0.tar.gz", "has_sig": false, "md5_digest": "f2c912d3885c7ced082b4c4ef7fe8fb0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32244, "upload_time": "2017-07-31T22:28:55", "url": "https://files.pythonhosted.org/packages/c1/0b/6027dd1a4c34dcb749cff424d6ff66e958150e0e0d8af95f23c9c9417a5a/gis_metadata_parser-1.0.tar.gz" } ], "1.1.3": [ { "comment_text": "", "digests": { "md5": "4b47eefe2bf4f13d24fdc7584f46c4af", "sha256": "46da6f83ec3a6b5fb1f3da3a31132157971ab3240efca2792bd92e91a9a53384" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "4b47eefe2bf4f13d24fdc7584f46c4af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 41412, "upload_time": "2018-06-05T23:17:19", "url": "https://files.pythonhosted.org/packages/13/b0/1a271033effcd466fec65e1af9d1aba9939379e3d37eb4990d449bc6fca5/gis_metadata_parser-1.1.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a7398ff3519a451c0a1b7432dacd61d7", "sha256": "21ec31c3944b4bfeddcda1285045b8e29495e9a3cd86872760f81566ce38a1c7" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.3.tar.gz", "has_sig": false, "md5_digest": "a7398ff3519a451c0a1b7432dacd61d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38346, "upload_time": "2018-06-05T23:17:21", "url": "https://files.pythonhosted.org/packages/bb/4d/2579afd782ed3644ddee1c792da827ce48cab388a61847e35a8f9e05385a/gis_metadata_parser-1.1.3.tar.gz" } ], "1.1.4": [ { "comment_text": "", "digests": { "md5": "0428d4930e359e55223f9bc38e2ab092", "sha256": "7097278a46cfd3f47b522a724c24072f7c81a7902fc7cb94b0a2d97beb7cf860" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "0428d4930e359e55223f9bc38e2ab092", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 41416, "upload_time": "2018-07-02T20:41:09", "url": "https://files.pythonhosted.org/packages/f3/98/4f6a48bbd40eb26eb55cc8fc1e7b451d362cb952f845d8744030f6f0e162/gis_metadata_parser-1.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2a30ac210cf4d0b8b81d5f8d7044e3ab", "sha256": "87f110fb892f733366ea9491ce9d5aaf28270e499d8fa7f4cb98a8636434e98f" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.4.tar.gz", "has_sig": false, "md5_digest": "2a30ac210cf4d0b8b81d5f8d7044e3ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38349, "upload_time": "2018-07-02T20:41:10", "url": "https://files.pythonhosted.org/packages/e8/e6/315691bcabecdd8013b91d26aee35e12a33ebc07b14157d2efcd8746b097/gis_metadata_parser-1.1.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0428d4930e359e55223f9bc38e2ab092", "sha256": "7097278a46cfd3f47b522a724c24072f7c81a7902fc7cb94b0a2d97beb7cf860" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "0428d4930e359e55223f9bc38e2ab092", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 41416, "upload_time": "2018-07-02T20:41:09", "url": "https://files.pythonhosted.org/packages/f3/98/4f6a48bbd40eb26eb55cc8fc1e7b451d362cb952f845d8744030f6f0e162/gis_metadata_parser-1.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2a30ac210cf4d0b8b81d5f8d7044e3ab", "sha256": "87f110fb892f733366ea9491ce9d5aaf28270e499d8fa7f4cb98a8636434e98f" }, "downloads": -1, "filename": "gis_metadata_parser-1.1.4.tar.gz", "has_sig": false, "md5_digest": "2a30ac210cf4d0b8b81d5f8d7044e3ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38349, "upload_time": "2018-07-02T20:41:10", "url": "https://files.pythonhosted.org/packages/e8/e6/315691bcabecdd8013b91d26aee35e12a33ebc07b14157d2efcd8746b097/gis_metadata_parser-1.1.4.tar.gz" } ] }