Использовать URL-адрес WSDL с XML с экранированными символами в качестве аргумента

#python #xml #django #soap #wsdl

#python #xml #django #soap #wsdl

Вопрос:

Я выполняю метод веб-службы SOAP, который получает 3 строковых аргумента с библиотекой suds.

Первым строковым аргументом должен быть XML, а 2 других — имя пользователя и пароль, это моя полурабочая реализация.

 from suds.client import Client
url = "http://www.jonima.com.mx:3014/sefacturapac/TimbradoService?wsdl"
client = Client(url)
client.service.timbrado(XML_AS_STRING_HERE, 'PRUEBA1', '12345678')
  

Когда первый параметр содержит экранированный символ (амперсанд, кавычки, апостроф, меньше, больше, чем), метод не работает, потому что сервер интерпретирует текст так, как если бы он не был экранирован. Если не содержит ни одного из этих символов, метод отлично работает

Пример XML без амперсанда работает http://dl.dropbox.com/u/1990697/no_amp.xml

Пример XML с амперсандом не работает http://dl.dropbox.com/u/1990697/with_amp.xml

Есть идеи, как я могу передать XML с экранированными символами?

Он не должен полагаться на suds, а на python. Я использую python 2.6 (как это могло бы быть с 2.7, если требуется)

Я также использую фреймворк Django, не знаю, может ли это быть полезно.


Дополнительная информация:

  • У меня нет доступа к изменению SOAP-сервера
  • Служба поддержки клиентов сообщила мне, что мои xml верны и что они работают для них, поэтому ошибка в моей реализации (или где-то в suds?)

Ответ №1:

Я думаю, что виновником здесь является библиотека suds. Когда вы отправляете экранированный xml в suds в качестве параметра client.service.timbrado метода, он также экранирует его. Однако он видит, что вы уже экранировали амперсанд следующим образом:

 ...
descripcion="EJEamp;amp;MPLO"
...
  

И он не экранирует его дальше (хотя должен). Вы должны запустить свой экранированный xml, xml.sax.saxutils.escape прежде чем передавать его client.service.timbrado .

Это должно привести к тому, что приведенный выше фрагмент xml будет выглядеть следующим образом:

 ...
descripcion="EJEamp;amp;amp;MPLO"
...
  

Когда я запускаю ваш код с дважды экранированным xml, я получаю следующий результат:

 <?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:timbradoResponse xmlns:ns2="http://sefactura.com">
            <return>
                <status>401 - Fecha y hora de generación fuera de rango</status>
            </return>
        </ns2:timbradoResponse>
    </S:Body>
</S:Envelope>
  

Это ошибка, касающаяся ваших данных (дата и время генерации вне диапазона), а не формата xml.

Комментарии:

1. действительно 🙂 рад, что смог помочь.

Ответ №2:

Вы легко можете «экранировать» любые значения XML, прежде чем они перейдут в службу. Проверьте http://wiki .python.org/moin/EscapingXml

 >>> from xml.sax.saxutils import escape
>>>
>>> escape("< amp; >")
'amp;< amp;amp; amp;>'
  

В прошлом это работало для меня, чтобы делать именно то, что вы описываете, передавать XML-данные по сети на страницу.

Согласно http://www.xmlnews.org/docs/xml-basics.html#references , просто экранирование данных перед их отправкой будет работать просто отлично.

Для работы с вашим примером XML

 ...
descripcion="EJEamp;MPLO"
...
  

после его прохождения будет

 ...
descripcion="EJEamp;amp;MPLO"
...
  

Комментарии:

1. Аргумент xml экранируется правильно, если вы видите источник данного dl.dropbox.com/u/1990697/with_amp.xml вы увидите правильно экранированный XML-файл. Приветствия…

2. поскольку вы уже экранируете символы, вы больше ничего не можете сделать со своей стороны, и служба работает… похоже, это ошибка с suds… хотя быстрый взгляд на их баг-трекер не показывает эту конкретную ошибку. Можете ли вы попробовать сделать то, что вы хотите сделать, с другой службой (чтобы посмотреть, работает ли ваш метод)? Вероятно, вы могли бы очень легко переключиться с использования suds на что-то другое (suds просто действительно является анализатором xml в конце дня … их много)

3. Спасибо, наконец, хитрость заключалась в том, чтобы снова убежать, это был вопрос галочки.

Ответ №3:

Вы пытались дважды экранировать их?

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

Комментарии:

1. Спасибо, если бы я мог отметить более одного варианта в качестве допустимого ответа, это также будет применено, так плохо, что я могу только дать положительный ответ.