Search layer in mxd's using Python

3329
4
Jump to solution
12-21-2015 07:29 AM
Yaron_YosefCohen
Occasional Contributor II

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

0 Kudos
1 Solution

Accepted Solutions
FreddieGibson
Occasional Contributor III

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

View solution in original post

4 Replies
WesMiller
Regular Contributor III

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
0 Kudos
FreddieGibson
Occasional Contributor III

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
Yaron_YosefCohen
Occasional Contributor II

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

0 Kudos
DanPatterson_Retired
MVP Emeritus

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