1

I'm trying to save all layers in my ArcMap mxd as .lyr files using the script below. However, I'm getting an error because some group layer names contain special characters (e.g. © : * ) and cannot be written into folder names.

How can I make sure special characters are ignored/replaced?

import os 
basepath = r'C:\Users\Anneka\Dropbox (The Rivers Trust)\CaBA_Data_Phase5\Layers' 
mxd = arcpy.mapping.MapDocument("CURRENT") 
for lyr in arcpy.mapping.ListLayers(mxd): 
 if lyr.isGroupLayer == True: 
 grpPath = os.path.join(basepath, str(lyr)) 
 if not os.path.exists(grpPath): 
 os.makedirs(grpPath) 
 else: 
 fn = os.path.join(basepath, str(lyr) + ".lyr") 
 lyr.saveACopy(fn) 

The error:

Runtime error 
Traceback (most recent call last):
 File "<string>", line 10, in <module>
 File "C:\Python27\ArcGIS10.6\Lib\os.py", line 157, in makedirs
 mkdir(name, mode)
WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: 'C:\\Users\\Anneka\\Dropbox (The Rivers Trust)\\CaBA_Data_Phase5\\Layers\\Issues\\Rivers\\WFD Classification Sites 2016 (EA)*'
PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Apr 30, 2019 at 22:00
0

2 Answers 2

2

You can use non-ascii characters in file/folder names. However, you can't use reserved characters or words in file/folder names.

If you are getting a UnicodeEncodeError: 'ascii' codec can't encode character etc... exception, you are trying to encode unicode to ascii when your script uses str(lyr) (not when you try to create a file/folder). Instead of doing that, just use the lyr objects longName property which is a unicode string. You can then just save your file as is.

You'll see something like ValueError: Layer: Unexpected error if your layer names contains reserved characters/words.

The reserved characters are:

  • < (less than)
  • > (greater than)
  • : (colon)
  • " (double quote)
  • / (forward slash)
  • \ (backslash)
  • | (vertical bar or pipe)
  • ? (question mark)
  • * (asterisk)

The reserved words are CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9

You could handle both the UnicodeEncodeError and ValueError using something like:

import os
import arcpy
def fix_name(name):
 replace = '_'
 reserved_chars = [u'<', u'>', u':', u'"', u'/', u'|', u'?', u'*'] # u'\\' is reserved, but we use as directory separator
 reserved_words = [u'CON', u'PRN', u'AUX', u'NUL',
 u'COM1', u'COM2', u'COM3', u'COM4', u'COM5', u'COM6', u'COM7', u'COM8', u'COM9',
 u'LPT1', u'LPT2', u'LPT3', u'LPT4', u'LPT5', u'LPT6', u'LPT7', u'LPT8', u'LPT9']
 for char in reserved_chars:
 name = name.replace(char, replace)
 name = os.sep.join([replace + b + replace if b.upper() in reserved_words else b for b in name.split(os.sep)])
 return name
basepath = r'C:\Temp'
mxd = arcpy.mapping.MapDocument(r"C:\Temp\Test.mxd") # "("CURRENT")
for lyr in arcpy.mapping.ListLayers(mxd):
 name = fix_name(lyr.longName)
 if lyr.isGroupLayer:
 grpPath = os.path.join(basepath, name)
 if not os.path.exists(grpPath):
 os.makedirs(grpPath)
 else:
 fn = os.path.join(basepath, name + ".lyr")
 lyr.saveACopy(fn)
 print("Saved: " + fn)

So for this:

enter image description here

The output is:

Saved: C:\Temp\Überwald\Group Layer\_NUL_.lyr
Saved: C:\Temp\Überwald\Group Layer\_LPT2_.lyr
Saved: C:\Temp\Überwald\Group Layer\Überwald Sub_Group Layer\Überwald Coastline.lyr
Saved: C:\Temp\Überwald\Group Layer\Überwald Sub_Group Layer\Überwald Base Map.lyr
Saved: C:\Temp\Temperature (°C).lyr
Saved: C:\Temp\A_B_.lyr
answered May 1, 2019 at 0:17
2
  • This almost worked! But it would seem that the issue is that some group names have special characters, and windows doesn't allow special characters in folder names (even though it does in individual file names) Commented May 1, 2019 at 9:44
  • @Anneka I have just tested with special characters in folder names and it works fine. What doesn't work is trying to use reserved characters as specified in docs.microsoft.com/en-us/windows/desktop/fileio/… Commented May 2, 2019 at 1:55
0

This is untested but, from reviewing Remove all special characters, punctuation and spaces from string at Stack Overflow, I think it should work:

import os 
basepath = r'C:\Users\Anneka\CaBA_Data_Phase_5\Layers' 
mxd = arcpy.mapping.MapDocument("CURRENT") 
for lyr in arcpy.mapping.ListLayers(mxd): 
 if lyr.isGroupLayer == True: 
 grpPath = os.path.join(basepath, str(lyr)) 
 if not os.path.exists(grpPath): 
 os.makedirs(grpPath) 
 else: 
 newLayerName = ''.join(e for e in str(lyr) if e.isalnum())
 fn = os.path.join(basepath, newLayerName + ".lyr") 
 lyr.saveACopy(fn) 
 print "Saved: " + fn 
answered Apr 30, 2019 at 22:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.