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 mxd
Finally, 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