Howdy!
I had a bunch of shp files inputted in my mxds. and we renamed these shp files and the link in my mxds got broken. The easiest way is to open the mxd, set the data source and click the renamed shp files or use the arc catalog. However, I need to do the fixing of broken links to 700 mxds., this can be overwhelming. I am trying to find a python code/script that can be used in order to fix these broken links but unfortunately, I can't find any that works. Can anyone help me with this? It will be greatly appreciated if anyone can give me a script for this.
Ps: I tried using this script from ArcGIS Help 10.1 but it is not working
<SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">import</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">arcpy</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">mxd</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">=</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">arcpy</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">mapping</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">MapDocument</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">(</SPAN><SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">r"C:\Project\Project.mxd"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">)</SPAN><SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">for</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">lyr</SPAN> <SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">in</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">arcpy</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">mapping</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">ListBrokenDataSources</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">(</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">mxd</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">):</SPAN> <SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">if</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">lyr</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">supports</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">(</SPAN><SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">"DATASOURCE"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">):</SPAN> <SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">if</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">lyr</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">dataSource</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">==</SPAN> <SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">r"C:\Project\Data\Transportation.gdb\MajorRoads"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">:</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">lyr</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">replaceDataSource</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">(</SPAN><SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">r"C:\Project\Data\Transportation.gdb"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">,</SPAN> <SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">"FILEGDB_WORKSPACE"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">,</SPAN> <SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">"Highways"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">)</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">lyr</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">name</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">=</SPAN> <SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">"Highways"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">mxd</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">.</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">saveACopy</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">(</SPAN><SPAN class="" style="color: #a31515; border: 0px; font-size: 11.44px;">r"C:\Project\Project2.mxd"</SPAN><SPAN class="" style="border: 0px; font-size: 11.44px;">)</SPAN><SPAN class="" style="color: #0000ff; border: 0px; font-size: 11.44px;">del</SPAN> <SPAN class="" style="border: 0px; font-size: 11.44px;">mxd</SPAN>
If it is a simple rename all "earthquake_PHI" to "earthquake_PHL", then this may give you an idea. If it is a bunch of renames, you may need to use a dictionary in the renaming.
<SPAN class="keyword token">import</SPAN> arcpy <SPAN class="keyword token">import</SPAN> os <SPAN class="keyword token">from</SPAN> arcpy <SPAN class="keyword token">import</SPAN> env <SPAN class="comment token"># path to search for mxd</SPAN> path <SPAN class="operator token">=</SPAN> r'C<SPAN class="punctuation token">:</SPAN>\Path\To\Use" oldShp <SPAN class="operator token">=</SPAN> <SPAN class="string token">"earthquake_PHI"</SPAN> <SPAN class="comment token"># old shapefile name without extension</SPAN> newShp <SPAN class="operator token">=</SPAN> <SPAN class="string token">"earthquake_PHL"</SPAN> <SPAN class="comment token"># for replaceDataSource - does not use ".shp"</SPAN> <SPAN class="comment token"># iterates through folder searching for mxds</SPAN> <SPAN class="keyword token">for</SPAN> fileName <SPAN class="keyword token">in</SPAN> os<SPAN class="punctuation token">.</SPAN>listdir<SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> fullPath <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>join<SPAN class="punctuation token">(</SPAN>path<SPAN class="punctuation token">,</SPAN>fileName<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>isfile<SPAN class="punctuation token">(</SPAN>fullPath<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">and</SPAN> fileName<SPAN class="punctuation token">[</SPAN><SPAN class="operator token">-</SPAN><SPAN class="number token">3</SPAN><SPAN class="punctuation token">:</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>lower<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">==</SPAN> <SPAN class="string token">'mxd'</SPAN><SPAN class="punctuation token">:</SPAN> mxd <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>mapping<SPAN class="punctuation token">.</SPAN>MapDocument<SPAN class="punctuation token">(</SPAN>fullPath<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> fullPath <SPAN class="keyword token">for</SPAN> lyr <SPAN class="keyword token">in</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>mapping<SPAN class="punctuation token">.</SPAN>ListLayers<SPAN class="punctuation token">(</SPAN>mxd<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">if</SPAN> lyr<SPAN class="punctuation token">.</SPAN>supports<SPAN class="punctuation token">(</SPAN><SPAN class="string token">"DATASOURCE"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">if</SPAN> oldShp <SPAN class="keyword token">in</SPAN> lyr<SPAN class="punctuation token">.</SPAN>dataSource<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"\t"</SPAN> <SPAN class="operator token">+</SPAN> lyr<SPAN class="punctuation token">.</SPAN>dataSource shpPath <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>dirname<SPAN class="punctuation token">(</SPAN>lyr<SPAN class="punctuation token">.</SPAN>dataSource<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"\t"</SPAN> <SPAN class="operator token">+</SPAN> shpPath shpFile <SPAN class="operator token">=</SPAN> os<SPAN class="punctuation token">.</SPAN>path<SPAN class="punctuation token">.</SPAN>basename<SPAN class="punctuation token">(</SPAN>lyr<SPAN class="punctuation token">.</SPAN>dataSource<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"\t"</SPAN> <SPAN class="operator token">+</SPAN> shpFile <SPAN class="comment token"># this will replace the data source in the mxd</SPAN> lyr<SPAN class="punctuation token">.</SPAN>replaceDataSource<SPAN class="punctuation token">(</SPAN>shpPath<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"SHAPEFILE_WORKSPACE"</SPAN><SPAN class="punctuation token">,</SPAN> newShp<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># if layer needs to be renamed</SPAN> lyr<SPAN class="punctuation token">.</SPAN>name <SPAN class="operator token">=</SPAN> newShp mxd<SPAN class="punctuation token">.</SPAN>save<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># save mxd changes, perhaps use: mxd.saveACopy(r"C:\Project\Output\\" + newname + ".mxd")</SPAN> <SPAN class="keyword token">del</SPAN> mxd<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Hello Randy,
Just tried this script and it worked! Thank you very much.
I also made a dictionary for renaming a bunch of shapefiles as you recommended. Thank you!
Jerome
Hello Dan,
Thanks for this.
this is our situation, we have a shp file named "earthquake_PHI.shp", and we renamed it manually to "earthquake_PHL.shp". This shapefile was used in over 700 mxds. we checked these mxds, and the links got broken. We wanted to find a way on how to set the data source again but with the newly renamed shpfile.
By the way, we still need to rename 70 shapefiles.
Thank you very much!
Hello Xander,
Thanks for your reply.
Yes, i run the code in version 10.1 and even tried it in version 10.3.
We modify the code by specifying the old and new locations and names of the shapefiles and we run the code.
The code works fine and there are no error messages, however, when we check the mxds, links are still broken.
Yes, we are working with shp files and not with features in a geodatabase.
We're here in this situation where we have a shp file named "earthquake_PHI.shp", and we renamed it to "earthquake_PHL.shp". This shapefile was used in over 700 mxds. we checked these mxds, and the links got broken. We wanted to find a way on how to set the data source again but with the newly renamed shpfile.
"Was there a process to the renaming that can be code?" We just renamed the shp and its extensions (.dbf, .shx, etc) manually inside a folder.
We have another situation where we didn't rename the shpfile ("earthquake_PHI.shp") anymore, instead we 'save as' another file called "earthquake_PHL.shp". In this case, we have now 2 shapefiles. Checking the mxds, links are not broken but the layer in mxd still has the old shapefile as its source, but we wanted to change it to the new shapefile by setting the data source. Is this possible with a script to set the data source in 700 mxds?
As Dan Patterson mentioned, with whatever script you find, you will need to some modifications. It sounds like you will want to start with a loop to find all your MXDs, and then loop through the feature layers in each file. Here's a code example that might be of interest: Write Broken Source List to Text File.
Can you explain a bit more about your situation. I am assuming that you are working with shape files (ending in .shp) and not a feature in a geodatabase. Were the shape files moved, renamed or both? If they were renamed, was there a logic/process to the renaming that can be written with code? If the files were moved, again, was there specific process used?
That code won't work without modification since you have to provide the paths to the projects (mxd's) and their data if the location of the data are not 'relative' to the projects. Renaming them along the way is going to further complicate things. Do you have some sort of 'old-new' name key that can facilitate the move?
If the number of projects to fix greatly outnumbers the number of shapefiles you renamed, then it may be best to backtrack and rename them back to their original names, until you can get the rest of this resolved.
It would be discouraging that renaming 3 shapefiles ruined 700 projects.
Do you have version 10.1? What is not working, any error messages? You will probably have to create a loop through the MXD's and specify what the old and new location and names of the shapefile are.
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.