ExpatError: неправильно сформирован (недопустимый токен) при использовании SimpleXMLRPCServer из-за диакритических символов

Мне потребовалось много времени, чтобы точно определить причину ошибки. Я пишу простой XML RPC-сервер, который позволяет просматривать каталоги и, возможно, выполнять другие операции только для чтения. Я уже сделал простой способ, чтобы перечислить все папки и файлы и представить их в виде словаря:

def list_dir(self, dirname):
    """Returns list of files and directories as a dictionary, where key is name and values is either 'file' or 'dir'"""
    dirname = os.path.abspath(os.path.join(self.server.cwd,dirname))
    #Check that the path doesn't lead above 
    if dirname.find(self.server.cwd)==-1:
        raise SecurityError("There was an attempt to browse in %s wthich is above the root working directory %s."%(dirname, self.server.cwd))
    check_for_valid_directory(dirname)
    #Looping through directory
    files = [i for i in os.listdir(dirname)]
    #Create associative array
    result = {}
    #Iterate through files
    for f in files:
        fullpath = os.path.join(dirname, f)
        #Appending directories
        if os.path.isdir(fullpath):
            result[f] = "dir"
        else:
            result[f] = "file" 

    print "Sending data", result   
    return result

Теперь, когда каталог содержит файл (или, скорее, папку) с именем Nová složka клиент получает ошибку вместо желаемого списка. Когда я удалил проблемное имя файла, я получил данные без ошибок. Я не думаю, что у библиотеки Python есть такое право - либо преобразование аргументов должно быть полным, включая любые юникодные данные, либо не присутствовать вообще.

Но в любом случае, как я должен кодировать данные, которые библиотека Python не может обработать?

1 ответ

Решение

Вы должны убедиться, что имена файлов и пути являются объектами Unicode, и что все имена файлов используют правильную кодировку. Последняя часть может быть немного хитрой, поскольку имена файлов POSIX являются байтовыми строками, и не требуется, чтобы все имена файлов в разделе были закодированы с одинаковой кодировкой. В этом случае вы мало что можете сделать, кроме как самостоятельно декодировать имена и как-то обрабатывать ошибки или возвращать имена файлов в виде двоичных данных вместо строк (в Юникоде).

Функции, связанные с именами файлов в os а также os.path возвращать строки Юникода, если они получают строки Юникода в качестве аргументов. Так что если вы убедитесь, что dirname имеет тип unicode вместо str затем os.listdir() будет возвращать строки Unicode, которые должны быть в состоянии пройти через XML-RPC.

Другие вопросы по тегам