1

I have read up on the ESRI technical article here.

Basically I had a corrupt feature class that I rebuilt from a backup and renamed. As I created more .mxd's with this renamed feature class, all .mxd's previous to the corruption now have broken sources. I found a code snippet on the article for replacing a data source. The problem is, I want to run this code on many .mxd's in a folder but this code only runs on single .mxd's. I have little python experience so I need some help here.

Side Note: I am delivering these .mxd files along with the FGDB to a client. I am batch running a script to enable relative links on all .mxd files. Will this affect the code I need to run on fixing data sources?

In this code, MajorRoads is being renamed to Highways.

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")
for lyr in arcpy.mapping.ListBrokenDataSources(mxd):
    if lyr.supports("DATASOURCE"):
        if lyr.dataSource == r"C:\Project\Data\Transportation.gdb\MajorRoads":
            lyr.replaceDataSource(r"C:\Project\Data\Transportation.gdb", "FILEGDB_WORKSPACE", "Highways")
            lyr.name = "Highways"
            mxd.saveACopy(r"C:\Project\Project2.mxd")
del mxd
  • 1
    I corrected the indenting of your code block to not contain errors, keep that in mind in relation to the answer I have given below. – GeoSharp Jan 25 '17 at 17:54
1

If I understand your question correctly, you want to know how to apply this code to many mxds not just one. To do this you can use the python module glob it is in the standard Python library. You would match all .mxds within a folder like this

import glob, os
in_folder = r'C:\the_folder\containing_mxds'
mxd_paths = glob.glob(os.path.join(in_folder, '*.mxd'))

Calling glob.glob in the snippet above will return a list of file paths that have an extension of .mxd. The * is a wildcard and matches all characters. From there you use your same code, with minor adjustments, but inside a loop that loops over the mxd paths in the list of mxds, mxd_paths. Like this:

for mxd_path in mxd_paths:
    mxd = arcpy.mapping.MapDocument(mxd_path)
    #perform the rest of your code here
    bfixed_layer = False
    for lyr in arcpy.mapping.ListBrokenDataSources(mxd):
        if lyr.supports("DATASOURCE"):
            if lyr.dataSource == r"C:\Project\Data\Transportation.gdb\MajorRoads":
                lyr.replaceDataSource(r"C:\Project\Data\Transportation.gdb", "FILEGDB_WORKSPACE", "Highways")
                lyr.name = "Highways"
                bfixed_layer = True
    #only save a copy of the mxd if you fixed the layer
    if bfixed_layer == True:
         #to save a copy with a different name, isolate the filename without extension
         mxd_base_name = os.path.splitext(os.path.basename(mxd_path))[0]
         new_mxd_path = os.path.join(os.path.dirname(mxd_path), mxd_base_name + '_2.mxd')
         mxd.saveACopy(new_mxd_path)

In the snippet above I basically used your method to create the new path name. However just appending a '_2' to the name, is not a very safe way to rename a file. If you wanted to be sure that the name was unique you can use os.path.exists before saving the new mxd. If the new file path exists, rather than appending '_2' to the existing file name, the time module can be used to create a unique time stamp which can be appended to your new file name. Something like this:

if os.path.exists(new_mxd_path):
    unique_time_stamp = str(int(round(time.time() * 1000)))
    new_mxd_path = os.path.join(os.path.dirname(mxd_path), mxd_base_name + unique_time_stamp + '.mxd')
    mxd.saveACopy(new_mxd_path)
  • Thank you for your help, I feel I am almost there but the script is only outputting one "mxd_2" as opposed to the whole folder. Any idea why this would happen? – gnarkilleptic Jan 25 '17 at 19:13
  • 2
    @gnarkilleptic yes if your loops are not properly embedded that would occur. See the updated code in my answer. If you found this helpful, upvotes are appreciated :-) – GeoSharp Jan 26 '17 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.