Hi,
I work with ArcGIS 10.3 and I try to search a specific layer (with data Source named "D:\desktop\Project\layers\1.jpg" ) in hundred of mxd's that spread in folder "D:\PROJECTS" and it divided to hundred of sub folders. I using python 2.7.8:
import arcpy,os,sys
import arcpy.mapping
from arcpy import env
env.workspace = r"D:\desktop\Project"
for mxdname in arcpy.ListFiles("*.mxd"):
mxd = arcpy.mapping.MapDocument(r"D:\desktop\Project\\" + mxdname)
dfList = arcpy.mapping.ListDataFrames(mxd, "*")
for df in dfList:
for lyr in arcpy.mapping.ListLayers(mxd, "", df):
if lyr.isGroupLayer == True: continue
if lyr.dataSource == r"D:\desktop\Project\layers\1.jpg":
print mxdname, mxdname.pathway
mxd.save()
del mxdFinally, I want that python will print all the mxd's source name that contain the specific layer I search for. When I run the code I get error:
project1.mxd
Traceback (most recent call last):
File "C:\Users\yaron.KAYAMOT\Desktop\idle.pyw", line 13, in <module>
print mxdname, mxdname.pathway
AttributeError: 'unicode' object has no attribute 'pathway'
Doe's anyone have a solution for this issue?
For clarity, i ask it in arcpy - Search MXDs with specific dataSource layer using Python - Geographic Information Systems Sta...
Thanks
Solved! Go to Solution.
If you're just needing the path to the map document on disk you could also just leverage the filePath property of the MapDocument class. In this case you'd just call mxd.filePath.
MapDocument
http://desktop.arcgis.com/en/desktop/latest/analyze/arcpy-mapping/mapdocument-class.htm
Otherwise, you can save yourself some un-needed code and stitch together the path from the workspace and the mxd name that you used to open the MapDocument. Once you add the walk logic it'd probably look something like the following:
import arcpy
from arcpy import mapping as m
from os import path, walk
def FindMaps(root_directory, path_to_find):
maps = []
for root, dirnames, filenames in walk(root_directory):
for fname in [f for f in filenames if f.endswith(".mxd")]:
mxdPath = path.join(root, fname)
if not path.isfile(mxdPath):
continue
mxd = m.MapDocument(mxdPath)
for df in m.ListDataFrames(mxd):
for lyr in m.ListLayers(mxd, data_frame=df):
if lyr.supports("DATASOURCE"):
if lyr.dataSource == path_to_find:
print(mxdPath)
maps.append(mxdPath)
break
return maps
You'll want to use Describe object properties—Help | ArcGIS for Desktop
for mxd in arcpy.ListFiles("*.mxd"):
print mxd
desc = arcpy.Describe(mxd)
if hasattr(desc, "catalogPath"):
print "CatalogPath: " + desc.catalogPath
If you're just needing the path to the map document on disk you could also just leverage the filePath property of the MapDocument class. In this case you'd just call mxd.filePath.
MapDocument
http://desktop.arcgis.com/en/desktop/latest/analyze/arcpy-mapping/mapdocument-class.htm
Otherwise, you can save yourself some un-needed code and stitch together the path from the workspace and the mxd name that you used to open the MapDocument. Once you add the walk logic it'd probably look something like the following:
import arcpy
from arcpy import mapping as m
from os import path, walk
def FindMaps(root_directory, path_to_find):
maps = []
for root, dirnames, filenames in walk(root_directory):
for fname in [f for f in filenames if f.endswith(".mxd")]:
mxdPath = path.join(root, fname)
if not path.isfile(mxdPath):
continue
mxd = m.MapDocument(mxdPath)
for df in m.ListDataFrames(mxd):
for lyr in m.ListLayers(mxd, data_frame=df):
if lyr.supports("DATASOURCE"):
if lyr.dataSource == path_to_find:
print(mxdPath)
maps.append(mxdPath)
break
return maps
Hi Freddie,
i added those 2 lines in line 5 in your code:
root_directory = r"D:\desktop\Project" path_to_find = r"D:\desktop\Project\layers\1.jpg"
and nothing happen- python just run with no result. I think i didn't understand where i should add variables root_directory and path_to_find
to the code
root_directory = r"D:\desktop\Project"
path_to_find = r"D:\desktop\Project\layers\1.jpg"
maps_found = FindMaps(root_directory,path_to_find)
beginning on line 25, then do something with maps_found like
print them, since it returns a list, they can be further processed