【问题标题】:Python zeep - Invalid tag name when binding names starts with a dot (.)Python zeep - 绑定名称以点(。)开头时标记名称无效
【发布时间】:2017-10-24 18:26:00
【问题描述】:

我试图让 zeep 打开一个 WSDL,该 WSDL 在名称的开头带有点绑定,并得到一个 ValueError: Invalid tag name '.USXMLWSSoapBinding' 错误消息。

WSDL 将绑定名称定义为:

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

我可以让它与其他语言和库一起使用,但 python 和 zeep 似乎不同意我的观点:

python -mzeep <wsdl>

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

【问题讨论】:

    标签: python soap wsdl zeep


    【解决方案1】:

    你可以通过unittest.mock修补Zeep的崩溃行为

    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 的人也会遇到同样的问题。

    【讨论】:

    • 我找到了另一个解决方案。您可以 1. 获取 WSDL 内容 2. 将“Problematic/Tag”替换为“Problematic-Tag” 3. 使用替换的内容创建 StringIO 实例 4. 使用 StringIO 对象创建 zeep 实例
    【解决方案2】:

    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 中进行更改并为“name”测试 attr_name 来使其更具选择性。

    更多细节

    我最近遇到了类似的东西,其绑定名称中包含“/”。

    我对 SOAP 和/或 XML 知之甚少,但据我所知,绑定名称是一个 QName,它由一个可选的 prefix 和一个 localpart(由 : 分隔)。前缀和本地部分是NCNamesNCName 是一个没有“:”的 XML NameName 是一个 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。] 名称中不允许使用的初始字符包括数字、变音符号、句号和连字符。

    What is an xs:NCName type and when should it be used?

    NCName 的实际限制 NCName 是它不能包含多个符号字符,如:、@、 $, %, &, /, +, ,, ;, 空白字符或不同的括号。 此外,NCName 不能以数字、或减号开头 字符,尽管它们可以稍后出现在 NCName 中。

    【讨论】:

      猜你喜欢
      • 2016-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      相关资源
      最近更新 更多