Оказывается, SUDS видит xml как тип 'string' (не unicode), так что это закодированные значения.
1) ФИЛЬТР:
badXML = "your bad utf-8 xml here" #(type <str>)
#Turn it into a python unicode string - ignore errors, kick out bad unicode
decoded = badXML.decode('utf-8', errors='ignore') #(type <unicode>)
#turn it back into a string, using utf-8 encoding.
goodXML = decoded.encode('utf-8') #(type <str>)
2) SUDS: см. https://fedorahosted.org/suds/wiki/Documentation#MessagePlugin
from suds.plugin import MessagePlugin
class UnicodeFilter(MessagePlugin):
def received(self, context):
decoded = context.reply.decode('utf-8', errors='ignore')
reencoded = decoded.encode('utf-8')
context.reply = reencoded
и
from suds.client import Client
client = Client(WSDL_url, plugins=[UnicodeFilter()])
Надеюсь, это кому-нибудь поможет.
Примечание: благодаря Джону Мачину !
См .: Почему декодер python заменяет больше, чем недопустимые байты из закодированной строки?
Python issue8271 относительно errors='ignore'
может встать на вашем пути здесь. Без этой ошибки, исправленной в python, «ignore» будет использовать следующие несколько байтов для удовлетворения длины
во время декодирования недопустимой последовательности байтов UTF-8, только
начальный байт и последующие байты теперь считаются недействительными,
вместо числа байтов, указанного начальным байтом
Проблема была исправлена в:
Python 2.6.6 rc1
Python 2.7.1 rc1 (и все будущие выпуски 2.7)
Python 3.1.3 rc1 (и все последующие версии 3.x)
Python 2.5 и ниже будет содержать эту проблему.
В приведенном выше примере "\xef\xbc</name".decode('utf-8', errors='ignore')
должен
вернуть "</name"
, но в «ошибочных» версиях python он возвращает "/name"
.
Первые четыре бита (0xe
) описывают 3-байтовый символ UTF, поэтому используются байты 0xef
, 0xbc
, а затем (по ошибке) 0x3c
('<'
).
0x3c
не является допустимым байтом продолжения, который в первую очередь создает недопустимый 3-байтовый символ UTF.
Исправленные версии python удаляют только первый байт и только допустимое продолжение байт, оставляя 0x3c
неиспользованным