Python zeep — недопустимое имя тега, когда имена привязок начинаются с точки (.)

Я пытаюсь заставить zeep открыть WSDL с привязками с точкой в ​​начале имени и получить сообщение об ошибке ValueError: Invalid tag name '.USXMLWSSoapBinding'.

WSDL определяет имя привязки как:

<wsdl:binding name=".USXMLWSSoapBinding" type="impl:USXMLWS">

Я могу заставить его работать с другими языками и библиотеками, но python и zeep, похоже, не согласны со мной:

python -mzeep <wsdl>

or

import zeep
client = zeep.Client('https://example.com/service.wsdl')

person ullarsokkur    schedule 24.05.2017    source источник


Ответы (2)


Вы можете исправить аварийное поведение Zeep через unittest.mock

from unittest import mock
from zeep import Client

def my_as_qname(value, nsmap, target_namespace=None):
    value = value.strip()

    if '/' in value:  # This is my fix for slash in value
        value = value.replace('/', '-')

    # More stuff that i removed in this snippet


with mock.patch('zeep.utils.as_qname', side_effect=my_as_qname):
   client = Client(wsdl)

В моем случае сбойный WSDL — это французское почтовое отделение «La Poste» — новый веб-сервис Colissimo. https://ws.colissimo.fr/sls-ws/SlsServiceWS/2.0?wsdl

Я предполагаю, что другие люди, пытающиеся использовать Zeep с ним, наткнутся на ту же проблему.

person Guibod    schedule 27.06.2019

TL;DR

Zeep использует lxml для разбора wsdl. Имена привязок, начинающиеся с точки, кажутся не совсем совместимыми с XML. Если вы не можете изменить имя привязки, вы можете обойти это, отредактировав lib\site-packages\zeep\utils.py в соответствии с тем, что было сделано для https://github.com/mvantellingen/python-zeep/issues/594

Например:

...
def qname_attr(node, attr_name, target_namespace=None):
    value = node.get(attr_name)
    if value is not None:
        return as_qname(value, node.nsmap, target_namespace)


def as_qname(value, nsmap, target_namespace=None):
    """Convert the given value to a QName"""
    value = value.strip()  # some xsd's contain leading/trailing spaces
   #KLUDGE for bindingnames that start with '.'
    if value.startswith('.'):
        print("Stripping leading '.' from:", value)
        value = value.lstrip('.') 
    if ':' in value:
        prefix, local = value.split(':')
    ...

Обратите внимание, что это может иметь непреднамеренные побочные эффекты; Это сработало для меня, но я мало тестировал, YMMV. Вы можете сделать его более избирательным, проверив value для определенных подстрок или внеся изменения в qname_attr и проверив attr_name также и для 'name'.

Немного подробнее

Недавно я столкнулся с чем-то подобным с именем привязки, в котором было «/».

Я очень мало знаю о SOAP и/или XML, но, насколько я понимаю, имя привязки — это QName, которое состоит из необязательного префикса и localpart (разделенные :). Префикс и локальная часть: NCNames; NCName – это XML Name без ':'; Имя — это Nmtoken с ограниченным набором начальных символов, включая точку.

Я не уверен, что эти ссылки на w3.org самые свежие, но они появились при поиске:

https://www.w3.org/TR/wsdl20/#component-Binding< /а>

Свойства компонента Binding следующие:

 {name} REQUIRED. An xs:QName
 ...

https://www.w3.org/TR/xml-names/#ns-qualnames

Qualified Names
In XML documents conforming to this specification, some names (constructs corresponding 
to the nonterminal Name) MUST be given as qualified names, defined as follows:

Qualified Name
[7]         QName           ::=    PrefixedName | UnprefixedName
[8]         PrefixedName    ::=    Prefix ':' LocalPart
[9]         UnprefixedName  ::=    LocalPart
[10]        Prefix          ::=    NCName
[11]        LocalPart       ::=    NCName

https://www.w3.org/TR/xml-names/#NT-NCName

[4]          NCName    ::=    Name - (Char* ':' Char*) /* An XML Name, minus the ":" */

https://www.w3.org/TR/REC-xml/#NT-Name

Имя — это Nmtoken с ограниченным набором начальных символов.] Запрещенные начальные символы для имен включают цифры, диакритические знаки, точку и дефис.

Что такое xs:NCName тип и когда его следует использовать?

Практические ограничения NCName Практические ограничения NCName заключаются в том, что оно не может содержать несколько символов, таких как :, @, $, %, &, /, +, ,, ;, пробелы или другие круглые скобки. Кроме того, NCName не может начинаться с цифры, точки или знака минус, хотя они могут появиться позже в NCName.

person dabbler    schedule 02.11.2018