Updating Custom Metadata Elements using Python automation. Export & Import Metadata

11519
9
Jump to solution
03-22-2013 08:01 AM
KamrulKashem
New Contributor III
Hi Guys,

I have recently been researching the topic of python and metadata.

Currently in our organisation we hold a mix of metadata elements from both FGDC and ISO, as well as a few custom elements we wanted to record such as copyright statements. We have a website that contains all the elements together in a nice form based view.

We have FME (Feature Manipulation Engine) models set up to update feature classes automatically however we want to be able to also automate the metadata update. Namely being the 'Last Updated' date element in our metadata

I have noticed that the arcpy.ExportMetadata_conversion tool is restricted to translating in a set format rather than exporting all elements recorded.

My question to you is:
Is there any way in Python to export a specific XML element from an SDE feature class, possibly export it into a temporary XML file then update the value of the element in question, then import it back into the SDE feature class?


Thank you!
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
I have made a script tool to do this.  Still testing it, but so far have had no problems with it.  It will find and replace text in a metadata file and you can choose specific trees to search through if you want (such as description).  This tool could probably use a little more tweaking but it has worked well for what I have used it for.  Below is a test showing that I am replacing "Cedar County" with "Johnson County" in the description tree.

[ATTACH=CONFIG]22933[/ATTACH][ATTACH=CONFIG]22934[/ATTACH][ATTACH=CONFIG]22935[/ATTACH]

Attached is the script tool if you want to check it out.


EDIT: I wanted to add that if you know the date text that you want to be replaced you could just set the tree parameter to 'None', and it will parse through the entire xml to replace the 'find string' in all parts of the metadata.  So if your last updated date is something like '08-21-2012', you could put that as the find string and set the replace string to '03-25-2013' (although in the xml file usually there are no dashes for the date, it gets formatted like that automatically so you would probably leave the dashes out).

View solution in original post

0 Kudos
9 Replies
curtvprice
MVP Esteemed Contributor
Is there any way in Python to export a specific XML element from an SDE feature class, possibly export it into a temporary XML file then update the value of the element in question, then import it back into the SDE feature class?


I think the easiest way to do this is

1. Create an empty metadata .xml file ("<metadata></metadata>")
2. Use the Import Metadata tool with the source your feature class and the target your empty file
3. use xmllib to manipulate the XML
4. Use the Import Metadata tool with the source the temp file and the target your feature class

You can get fancier using xslt stylesheets and the XML Transformation tool, but, it seems to me the above approach would be easier if you are just adding or updating a single element.

[thread]51445[/thread]
0 Kudos
by Anonymous User
Not applicable
I have made a script tool to do this.  Still testing it, but so far have had no problems with it.  It will find and replace text in a metadata file and you can choose specific trees to search through if you want (such as description).  This tool could probably use a little more tweaking but it has worked well for what I have used it for.  Below is a test showing that I am replacing "Cedar County" with "Johnson County" in the description tree.

[ATTACH=CONFIG]22933[/ATTACH][ATTACH=CONFIG]22934[/ATTACH][ATTACH=CONFIG]22935[/ATTACH]

Attached is the script tool if you want to check it out.


EDIT: I wanted to add that if you know the date text that you want to be replaced you could just set the tree parameter to 'None', and it will parse through the entire xml to replace the 'find string' in all parts of the metadata.  So if your last updated date is something like '08-21-2012', you could put that as the find string and set the replace string to '03-25-2013' (although in the xml file usually there are no dashes for the date, it gets formatted like that automatically so you would probably leave the dashes out).
0 Kudos
KamrulKashem
New Contributor III
Wow, both of you have been immense help! It shows that with a little python magic anything can be achieved even with non-standard metadata elements!

I will try the various methods posed on this thread and come back to you with feedback!

Keep them coming, these ideas need to be out on the public domain... automating metadata is the way forward! Especially due to the fact I can link these onto our already existing automatic update models on the data.
0 Kudos
TracyJones
New Contributor III
I have made a script tool to do this.  Still testing it, but so far have had no problems with it.  It will find and replace text in a metadata file and you can choose specific trees to search through if you want (such as description).  This tool could probably use a little more tweaking but it has worked well for what I have used it for.  Below is a test showing that I am replacing "Cedar County" with "Johnson County" in the description tree.

[ATTACH=CONFIG]22933[/ATTACH][ATTACH=CONFIG]22934[/ATTACH][ATTACH=CONFIG]22935[/ATTACH]

Attached is the script tool if you want to check it out.


EDIT: I wanted to add that if you know the date text that you want to be replaced you could just set the tree parameter to 'None', and it will parse through the entire xml to replace the 'find string' in all parts of the metadata.  So if your last updated date is something like '08-21-2012', you could put that as the find string and set the replace string to '03-25-2013' (although in the xml file usually there are no dashes for the date, it gets formatted like that automatically so you would probably leave the dashes out).


Hi Caleb,

I implemented this script - thanks for sharing. I'm having an issue, the first time I run it using FGDC to ARCGIS it works perfect then I run it again on the same object and it blanks out the metadata on that object. Is a translator nessesary?

Also do you think there is a way to do a batch source?

Thanks,

Tracy
0 Kudos
by Anonymous User
Not applicable
the first time I run it using FGDC to ARCGIS it works perfect then I run it again on the same object and it blanks out the metadata on that object. Is a translator nessesary?


The reason why this will only work once when you do the FGDC to ARCGIS is because the metadata will be upgraded to the new ArcGIS format.  Therefore, when you run it again you will need to use the appropriate translation since the upgraded metadata is no longer the FGDC format.  It will work again once you apply the correct translation (ex. ArcGIS TO FGDC).  All of these will apply the translation because that is the only way you are able to change the metadata.  It has to be exported to a xml file that can be edited, then imported back into the feature class (this is where it is automatically upgraded to the new ArcGIS format).  Once you have ran the tool once, if you want to do another edit on the metadata you will have to change the Export xml Format parameter to one of the ones that transform from ArcGIS to another format (ArcGIS to FGDC for example).

There is one way that you can skip the translations, but this only works with shapefiles because it accesses the shapefile's .xml file (FGDC to FGDC (Shapefile Only) option).

You could definitely do this in a batch process style:

import arcpy
from metadata_ArcGIS_format2 import *

# Set env workspace
arcpy.env.workspace = r'G:\some\geodatabase.gdb'

# Variables
export = 'FGDC to ArcGIS'
tree = 'Description'


# Loop thru gdb to edit metadata for each fc
#
for fc in arcpy.ListFeatureClasses():
    # change all instances of Cedar County to Johnson County
    # source and target are the same to change original metadata
    EditMetadataText(fc, fc, 'Cedar County', 'Johnson County', export, tree)
    print 'Updated metadata for %s' %fc

print 'Finished editing metadata for all feature classes'
   


To make sure you can properly import the module make sure to run this script from the same directory as the tool or the metadata_ArcGIS_format2.py script in your PYTHONPATH.
0 Kudos
TracyJones
New Contributor III
Thanks Caleb,

I will give this a try, another quick question if you don't mind. When you are using these translators are they changing the underlying metadata structure? I'm concerned with using all of these translators and then basically screwing up the metadata? We no longer use FGDC we've migrated our standard to ISO (synonymous with ArcGIS I thought?)

Do you think there may be a way to incorporate the "Metadata Importer" tool instead which only asks for source and target? My python skills are a lot less than yours but I'm willing to try this is you think it would work.

Thanks again,

Tracy
0 Kudos
by Anonymous User
Not applicable
Yes, the translators do change the underlying metadata structure, but all the metadata elements should still remain.  You should be able to just use the "FGDC to ISO 19139" to get to your desired ISO format.  As for the Metadata Importer, my tool does use the import metadata tool.  This is set automatically for you based on what export format you use.  For example if you use the "FGDC to ISO 19139" export, my tool is designed to make the changes then it will import the updated metadata back to the target using the 'FROM_ISO_19139' translation (since it was exported to ISO format, it will be imported FROM_ISO). 

This is precisely why I have it set up to have a source parameter and a target parameter.  You can set these to both the same feature class to update the original, but I set it up so you can create a back up as the target and use the original as the source so you can perform the metadata update and compare the original metadata to the updated metadata to make sure everything is there before changing the original metadata. 

Below are the dictionaries the code uses that choose the appropriate import based on the export format parameter:

    # Set up export and import types, import is derived from export type
    export_dict = {'ArcGIS to FGDC' : 'ARCGIS2FGDC.xml',
                   'ArcGIS to ISO 19139' : 'ARCGIS2ISO19139.xml',
                   'FGDC to ArcGIS' : 'FGDC2ESRI_ISO.xml',
                   'FGDC to ISO 19139' : 'FGDC2ISO19139.xml',
                   'ISO 19139 to ArcGIS' : 'ISO19139_2ESRI_ISO.xml',
                   'ArcGIS or ESRI-ISO to ISO 19139' : 'ESRI_ISO2ISO19139.xml'}

    import_dict = {'ArcGIS to FGDC' : 'FROM_FGDC',
                   'ArcGIS to ISO 19139' : 'FROM_ISO_19139',
                   'FGDC to ArcGIS' : 'FROM_ARCGIS',
                   'FGDC to ISO 19139' : 'FROM_ISO_19139',
                   'ISO 19139 to ArcGIS' : 'FROM_ESRIISO',
                   'ArcGIS or ESRI-ISO to ISO 19139' : 'FROM_ISO_19139'}


My tool really only has 3 basic processes:

1. exports metadata to desired format as a stand alone xml file
2. does the find and replace text operation on the stand alone xml file
3. imports the updated xml file back into the feature class
0 Kudos
ChrisGraves1
New Contributor II
Hi Caleb,

Thankyou for sending this through v.helpful indeed. Quick query with regards to running the script via the tool you packaged up. What parameters did you set in the script properties (see attached). Also will it work if the find text is blank? For example we are looking to update the 'tag' with 'data downloaded then date' however the 'tag' would be blank.

Thanks,
Chris
0 Kudos
by Anonymous User
Not applicable
Chris,

It has been a long time since I have looked at or used this tool.  But I am pretty sure it won't work on a blank tag since it has to find text in order to replace it.  If you are wanting to look at replacing blank tags, I'd suggest using Python's Element" rel="nofollow" target="_blank">https://docs.python.org/2/library/xml.etree.elementtree.html... Tree module.  This module allows for lower level access to modifying tags.

To set up the tool I provided, change the tool" rel="nofollow" target="_blank">http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//... validator class script to this:

import arcpy
class ToolValidator(object):
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed."""

    self.params[4].filter.list = ['ArcGIS to FGDC',
                       'ArcGIS to ISO 19139',
                       'FGDC to ArcGIS',
                       'FGDC to ISO 19139',
                       'ISO 19139 to ArcGIS',
                       'ArcGIS or ESRI-ISO to ISO 19139',
      'FGDC to FGDC (Shapefile Only)']

    # List for trees
    self.params[5].filter.list = ['None','Summary','Description',
                                  'Credits','Title',
      'Use limitations',
                                  'Overview Description']


    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return


And use this screenshot to fill out the params.
[ATTACH=CONFIG]33782[/ATTACH]
0 Kudos