我试图让zeep打开一个在名称开头带有点绑定的WSDL,并得到一个ValueError:无效的标签名称'。USXMLWSSoapBinding' 错误消息。
WSDL 将绑定名称定义为:
<wsdl:binding name=".USXMLWSSoapBinding" type="impl:USXMLWS">
我可以让它与其他语言和库一起工作,但 python 和 zeep 似乎不同意我的观点:
python -mzeep <wsdl>
或
import zeep
client = zeep.Client('https://example.com/service.wsdl')
您可以通过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与它一起使用的人会偶然发现同样的问题。
TL;博士
Zeep 使用 lxml 来解析 wsdl。以点开头的绑定名称似乎不符合严格的 XML 标准。如果无法更改绑定名称,则可以通过按照为 https://github.com/mvantellingen/python-zeep/issues/594 执行的操作编辑libsite-packageszeeputils.py
来解决此问题
例如:
...
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。您可以通过测试特定子字符串的值来使其更具选择性,或者更改qname_attr
并测试"name"的attr_name。
更多细节
我最近遇到了类似的东西,其中有一个包含"/"的绑定名称。
我对 SOAP 和/或 XML 知之甚少,但据我所知,绑定名称是QName,它由一个可选的前缀和一个本地部分(用 :) 分隔)组成。前缀和局部部分是NCNames;NCName是一个不带":"的 XML名称;名称是具有一组受限的初始字符(包括句号(点))的Nmtoken。
我不确定这些 w3.org 参考文献是否是最新的,但它们是我搜索时出现的参考资料:
https://www.w3.org/TR/wsdl20/#component-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 中。