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)*'
0

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
  • 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) – Anneka May 1 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/… – user2856 May 2 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  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.