Как вы можете настроить xmlrpclib для интерпретации пользовательских типов?

У меня были проблемы с решением этой проблемы в течение нескольких дней, и я не смог найти какой-либо полезный ресурс по этому поводу в Интернете, поэтому я поделюсь своими выводами по этому поводу для дальнейшего использования:

Клиент Python 2.7 xmlrpclib имеет типы, определенные встроенным стандартом XMLRPC, а также несколько общих расширений. Однако другие XMLRPC-серверы, такие как Apache, иногда используют свои собственные типы или помещают расширения в специальные пространства имен и т. Д.

Например, когда вы отправляете 8-байтовое целое число с помощью Apache (на которое не распространяется стандарт XMLRPC), он отправляет следующий ответ:

<methodResponse xmlns:ex="http://ws.apache.org/xmlrpc/namespaces/extensions">
    <params>
        <param>
            <value>
                <ex:i8>123456789</ex:i8>
            </value>
        </param>
    </params>
</methodResponse>

Если вы наивно попытаетесь обработать эти типы с помощью Python, вы получите пустой результат кортежа. Как я могу настроить xmlrpclib для обработки таких случаев?


person nijansen    schedule 18.09.2013    source источник


Ответы (1)


Внутренне xmlrpclib использует xmlrpclib.Unmarshaller для отправки ответов. Unmarshaller имеет словарь dispatch, в котором каждому типу назначена функция, которая будет его обрабатывать.

На самом деле заставить пример вопроса работать довольно легко, потому что xmlrpclib уже может обрабатывать i8, и нам нужно только переназначить ex:i8 на это:

xmlrpclib.Unmarshaller.dispatch['ex:i8'] = xmlrpclib.Unmarshaller.dispatch['i8']

Но для большего количества настраиваемых типов может потребоваться написать о функциях диспетчеризации. Они предназначены для определения в Unmarshaller, поэтому типичная функция диспетчеризации выглядит так:

def end_int(self, data):
    self.append(int(data))
    self._value = 0
dispatch['i8'] = end_int

_value = 0 просто указывает на то, что отправка прошла успешно. Итак, если бы у нас было

<methodResponse>
    <params>
        <param>
            <value>
                <mycustom>some value</mycustom>
            </value>
        </param>
     </params>
</methodResponse>

мы могли бы определить:

def mycustom_parser(unmarshaller, data):
    unmarshaller.append(data.split())
    unmarshaller._value = 0
xmlrpclib.Unmarshaller.dispatch['mycustom'] = mycustom_parser
person nijansen    schedule 18.09.2013