Python minidom и UTF-8 в кодировке XML с хеш-ссылками - PullRequest
2 голосов
/ 12 января 2011

Я испытываю некоторые трудности в моем домашнем проекте, где мне нужно проанализировать SOAP-запрос.SOAP генерируется с помощью gSOAP и включает строковые параметры со специальными символами, такими как датские буквы «æøå».

gSOAP создает запросы SOAP с кодировкой UTF-8 по умолчанию, но вместо отправки специальных chatacters в необработанном формате (т. е. байты C3A6 для специального символа «æ») он посылает то, что я считаю так называемыми символьными хэш-ссылками (т. е. ¦¦).

Я не совсем понимаю, почему gSOAP делает это так, как я могувижу, что он пометил входящую полезную нагрузку как кодируемую в UTF-8 в любом случае (Content-Type: text / xml; charset = utf-8), но это помимо вопроса (я думаю).

В любом случае яугадайте, что gSOAP, вероятно, подчиняется правилам транспорта, или как?

Когда я анализирую запрос от gSOAP в python с помощью xml.dom.minidom.parseString (), я получаю значения элементов в виде объектов Unicode, что хорошо, но символссылки на хеш-коды не декодируются как коды символов UTF-8.Он удаляет ссылки на хеш-символы, но не декодирует строку впоследствии.В конце концов, у меня есть строковый объект Unicode с кодировкой UTF-8:

Так что, если строка «æble» содержится в XML, это происходит следующим образом в запросе:

"æble"

После анализа XML строка Unicode в элементе данных текстового узла DOM выглядит следующим образом:

u'\xc3\xa6ble'

Я ожидаю, что это будет выглядеть так:

u'\xe6ble'

Что я делаюнеправильно?Должен ли я удалить XML-файл SOAP перед его синтаксическим анализом, или это где-то еще, я должен искать решение, может быть, gSOAP?

Заранее спасибо.

С наилучшими пожеланиями Jakob Simon-Gaarde

Ответы [ 5 ]

1 голос
/ 12 января 2011

æble на самом деле æble.

Чтобы получить ожидаемую строку Юникода u'\xe6ble' после анализа, строка в запросе должна быть æble.

0 голосов
/ 12 января 2011

Если кто-то не скажет мне, что gSOAP не производит допустимый кодированный XML-код SOAP: (см. http://pastebin.com/raw.php?i=9NS7vCMB или кодовый блок ниже), я не вижу другого решения, кроме ссылки на хеш-код unescape перед анализом XML.

Конечно, как отметил Джон Мачин, я не могу удалить управляющие символы XML, такие как "<" и ">".

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:ShopService"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><ns1:createCompany><company-code>DK-123</company-code><name>&#195;&#166;ble</name></ns1:createCompany></SOAP-ENV:Body></SOAP-ENV:Envelope>

/ Якоб

0 голосов
/ 12 января 2011

Обратите внимание, что

In [5]: 'æ'.encode('utf-8')
Out[5]: '\xc3\xa6'

Итак, у нас есть объект Unicode u'\xc3\xa6', и нам действительно нужен строковый объект '\xc3\xa6'. Это преобразование можно выполнить с помощью кодека raw-unicode-escape:

In [1]: text=u'\xc3\xa6'
In [2]: text.encode('raw-unicode-escape')
Out[2]: '\xc3\xa6ble'

In [3]: text.encode('raw-unicode-escape').decode('utf-8')
Out[3]: u'\xe6'

In [4]: print(text.encode('raw-unicode-escape').decode('utf-8'))
æ
0 голосов
/ 12 января 2011

Вот как убрать такие вещи: http://effbot.org/zone/re-sub.htm#unescape-html

Однако основная проблема заключается в том, что вы и / или этот "gSOAP" (URL, пожалуйста) делаете ...

Ваш пример символа - ЛАТИНСКАЯ МАЛЕНЬКАЯ ЛИГАТУРА AE (U + 00E6). Как вы говорите, закодированный в UTF-8, это \xc3\xa6. 0xc3 == 195 и 0xa6 == 166. 0xe6 == 230. Выход вашего персонажа должен производить '&#230;', а не '&#195;&#166;'.

Однако похоже, что он сначала кодирует в UTF-8, а затем выполняет экранирование.

Что вам нужно сделать, это показать нам в мельчайших подробностях код, который вы используете вместе с диагностическими отпечатками (используя функцию repr (), чтобы мы могли видеть тип и однозначно представленное содержимое) каждого str и unicode объект, участвующий в процессе. Также предоставьте документы для API (ов) gSOAP, которые вы используете.

На получающей стороне, пожалуйста, покажите нам repr () необработанного XML, который вы получаете.

Редактировать в ответ на этот комментарий на другой ответ: "" "Проблема в том, что minidom.parseString (), похоже, не экранирует хэш-представление символа перед его декодированием в unicode." ""

Он (и любой другой синтаксический анализатор XML) {не делает, не может в общем случае и не должен} не сохранять числовые ссылки на символы или предопределенные символьные объекты ДО декодирования.

(1) не покинет "&#60;" до "<" взорвется

(2) к чему бы вы поехали "&#256"? "\xc4\x80"

(3) как он вообще мог исчезнуть, если кодировка была UTF-16xx?

0 голосов
/ 12 января 2011

Еще немного подробнее о моей проблеме.Проект, который я создаю, использует wsgi.Запрос SOAP извлекается с использованием environ['wsgi.input'].read().Кажется, всегда возвращается необработанная строка.Я создал функцию, которая удаляет хэши символов:

def unescape_hash_char(req):
  pat = re.compile('&#(\d+);',re.M)
  parts = pat.split(req)
  a=0
  ret = ''
  for p in parts:
    if a%2:
      n = chr(int(p))
    else:
      n = p
    ret += n
    a+=1
  return ret

После этого я анализирую XML и получаю ожидаемый результат.если это хорошее решение.Также я написал эту функцию, потому что я не смог найти функцию для выполнения работы в стандартных модулях Python, такая функция существует?

...