How do I edit metadata with Python?

05-17-2021 09:54 AM
New Contributor


I need some help if you all are able to help me. I was tasked to edit the metadata in our enterprise SQL server database for many feature classes. I tried to follow these instructions in the "Update metadata with Python scripts" section located here: Edit metadata for many ArcGIS items—Help | Documentation but I think I am missing some steps. I tried editing some of the code ESRI posted to better fit my needs but I am not sure I did that correctly. I am not a programmer, but I try my best.

I am trying to update the following fields in the ArcGIS metadata:


> Distributor

     >Contact information - distributor

          > Organization's name "my Company's name goes here"

          >Contact's Role "Distributor"

               >Contact information


                         >Voice "My Company's phone number goes here"


                         >Type "Physical"

                        >City "My city goes here"

                        >Administrative Area "My State goes here"

                        >Postal Code "My zip code goes here"

                        >Country "My country goes here"

                        >E-Mail Address "My company's email address goes here"

1) I am not sure how to write the code to connect to the database.

2) I am sure I will need to iterate through the database for each feature classes but I am not sure how to do this.

I am using ArcGIS Pro 2.7 if that helps. I also have access to ArcMap 10.8 but I would prefer to do this in ArcGIS Pro.

Below is the code I have so far. I got the tag information from looking at an exported xml file. Hope I got them right. I also commented out some on the code for testing purposes.

# batch update metadata for datasets in a folder

import os, sys
import arcpy
import xml.etree.ElementTree as ET

# arcpy environments
arcpy.env.overwriteOutput = "True"

# Script arguments...
Source_Metadata = arcpy.GetParameter(0)

# Local variables
# new purpose text
newPurpose = "This is new text for an existing Purpose metadata element."
newCredits = "This is text for a new Credits metadata element."

#newcntorg = "My Company information"
#newcntvoice = "My Company's phone number"
#newaddrtype = "physical"
#newcity = "My City goes here"
#newstate = "My State goes here"
#newpostal = "My zip code goes here"
#newcountry = "My country goes here"
#newcntemail = "My company's email goes here"

# install location
dir = arcpy.GetInstallInfo("desktop")["InstallDir"]

# stylesheet to use
copy_xslt = r"{0}".format(os.path.join(dir,"C:\Program Files (x86)\ArcGIS\Desktop10.7\Metadata\Stylesheets\gpTools\exact copy of.xslt"))
arcpy.AddMessage("XSLT: {0}".format(copy_xslt))

def update_metadata(root):
num_elements = 0

# modify purpose element's text
# there is only supposed to be one purpose element in metadata
# replace purpose element text if element exists
# if element doesn't exist, do nothing
purposeEls = root.findall(".//idPurp")
for element in purposeEls:
if element.text is not None:
element.text = newPurpose
num_elements += 1

#cntorgEls = root.findall(".//idcntorg")
#for element in cntorgEls:
#if element.text is not None:
#element.text = newcntorg
#num_elements += 1

#cntvoiceEls = root.findall(".//idcntvoice")
#for element in cntvoiceEls:
#if element.text is not None:
#element.text = newcntorg
#num_elements += 1

#addrtypeEls = root.findall(".//idaddrtype")
#for element in addrtypeEls:
#if element.text is not None:
#element.text = newaddrtype
#num_elements += 1

#cityEls = root.findall(".//idcity")
#for element in cityEls:
#if element.text is not None:
#element.text = newcity
#num_elements += 1

#stateEls = root.findall(".//idstate")
#for element in stateEls:
#if element.text is not None:
#element.text = newstate
#num_elements += 1

#postalEls = root.findall(".//idpostal")
#for element in postalEls:
#if element.text is not None:
#element.text = newpostal
#num_elements += 1

#countryEls = root.findall(".//idcountry")
#for element in countryEls:
#if element.text is not None:
#element.text = newcountry
#num_elements += 1

#cntemailEls = root.findall(".//idcntemail")
#for element in cntemailEls:
#if element.text is not None:
#element.text = newcntemail
#num_elements += 1

# add credits element to dataIdInfo parent, if the parent exists
# ISO allows many dataIdInfo groups; ArcGIS generally supports only one, get the 1st
# ISO allows many idCredit elements: 1st on Item Description page, all on Resource Details page
# always append new idCredit element to 1st dataIdInfo with appropriate text
# existing idCredit elements remain in place
dataIdInfoEls = root.findall("./dataIdInfo[1]")
for element in dataIdInfoEls:
if element:
newCreditEl = ET.SubElement(element,"idCredit")
newCreditEl.text = newCredits
num_elements += 1

return num_elements

for item in Source_Metadata:
arcpy.AddMessage("Item: {0}".format(item))

# temporary XML file
xmlfile = arcpy.CreateScratchName(".xml",workspace=arcpy.env.scratchFolder)
#arcpy.AddMessage("Temporary XML file: {0}".format(xmlfile))

# export xml
arcpy.XSLTransform_conversion(item, copy_xslt, xmlfile, "")

# read in XML
tree = ET.parse(xmlfile)
root = tree.getroot()

changes = update_metadata(root)
#arcpy.AddMessage("number of elements updated: {0}".format(changes))

if changes > 0:
# save modifications to XML
#arcpy.AddMessage("Saving changes to temporary file...")

# import result back into metadata
arcpy.AddMessage("Saving updated metadata with the item...")
arcpy.MetadataImporter_conversion(xmlfile, item)
arcpy.AddMessage("No changes to save")

arcpy.AddMessage('Finished updating metadata for all source metadata items')


Thank you all in advance!

1 Reply
MVP Esteemed Contributor

# stylesheet to use
copy_xslt = r"{0}".format(os.path.join(dir,"C:\Program Files (x86)\ArcGIS\Desktop10.7\Metadata\Stylesheets\gpTools\exact copy of.xslt"))
arcpy.AddMessage("XSLT: {0}".format(copy_xslt))

Arcgis Pro doesn't use XLSTs and I'm pretty sure the Metadata importer doesn't work in Pro either. I don't see it in the tools anyway.  Check here for a list of metadata tools that are no longer suppported.

What has worked for me is to create a generic metadata page with typical contacts, dates, usage, etc  export that to an xml.  Then I import it to a new feature class and make any adjustments as needed.

That should just about do it....
0 Kudos