2017-03-03 116 views
0

我发现此问题:https://mail.python.org/pipermail/soap/2013-June/001120.html 我有同样的问题,并且找不到答案。请帮忙。Spyne:请求输入参数具有不同命名空间

我正在实施spyne中的一些现有的WSDL,我 遇到一个问题,其中我有请求包含多个 名称空间。例如,我有一个看起来像一个请求:

<?xml version='1.0' encoding='UTF-8'?> 
<soapenv:Envelope xmlns:soapenv="schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header> 
    </soapenv:Header> 
    <soapenv:Body> 
    <a:Foo xmlns:a="www.example.com/schema/a" AttrA="a1" AttrB="b2"> 
     <b:Baz xmlns:b="www.example.com/schema/b" AttrC="c3"/> 
     <a:Bar>blah</a:Bar> 
    </a:Foo> 
    </soapenv:Body> 
</soapenv:Envelope> 

当我发出这个请求,我得到以下回:

<?xml version='1.0' encoding='utf-8'?> 
<senv:Envelope xmlns:senv="schemas.xmlsoap.org/soap/envelope/"> 
    <senv:Body> 
    <senv:Fault> 
     <faultcode>senv:Client.SchemaValidationError</faultcode> 
     <faultstring> 
     <string>:1:0:ERROR:SCHEMASV:SCHEMAV_ELEMENT_CONTENT: 
     Element '{www.example.com/schema/b}Baz': This element 
     is not expected. Expected is one of (
     {www.example.com/schema/a}Baz, 
     {www.example.com/schema/a}Bar).</faultstring> 
     <faultactor></faultactor> 
    </senv:Fault> 
    </senv:Body> 
</senv:Envelope> 

我一直在寻找的文件和设置选项,并到目前为止 什么都没有让我过去这个凹凸。这是目前可能与 spyne?我是否需要做更多并解析in_document?任何输入将不胜感激 。

的更多详细的代码我已经搞乱:

from spyne.model.primitive import Unicode 
from spyne.model.complex import Iterable, XmlAttribute, ComplexModel, 
ComplexModelMeta, ComplexModelBase 
from spyne.service import ServiceBase 
from spyne.protocol.soap import Soap11 
from spyne.application import Application 
from spyne.decorator import srpc, rpc 

class BazBase(ComplexModelBase): 
    __namespace__ = "www.example.com/schema/b" 
    __metaclass__ = ComplexModelMeta 

class Baz(BazBase): 
    Thing = Unicode 
    AttrC = XmlAttribute(Unicode) 

class FooService(ServiceBase): 
    __namespace__ = "www.example.com/schema/a" 

    @rpc(XmlAttribute(Unicode), XmlAttribute(Unicode), Baz, Unicode, 
_returns=Iterable(Unicode)) 
    def Foo(ctx, AttrA, AttrB, Baz, Bar): 
     yield 'Hello, %s' % Bar 

app = Application([FooService], 
    "www.example.com/schema/a", 
    in_protocol=Soap11(validator='lxml'), 
    out_protocol=Soap11(), 
) 

谢谢!

回答

2

所以,这里是它如何工作的:

from spyne import Unicode, Iterable, XmlAttribute, ComplexModel, \ 
    ServiceBase, Application, rpc 
from spyne.protocol.soap import Soap11 


NS_B = "www.example.com/schema/b" 


class Baz(ComplexModel): 
    __namespace__ = NS_B 

    Thing = Unicode 
    AttrC = XmlAttribute(Unicode) 


class FooCustomRequest(ComplexModel): 
    AttrA = XmlAttribute(Unicode) 
    AttrB = XmlAttribute(Unicode) 
    Bar = Baz.customize(sub_ns=NS_B) 
    Baz = Unicode 


class FooService(ServiceBase): 
    @rpc(FooCustomRequest, _returns = Iterable(Unicode), 
     _body_style='bare') 
    def Foo(ctx, req): 
     AttrA, AttrB, Baz, Bar = \ 
      req.AttrA, req.AttrB, req.Baz, req.Bar 
     yield 'Hello, %s' % Bar 


application = Application([FooService], 
    tns="www.example.com/schema/a", 
    in_protocol=Soap11(validator='soft'), 
    out_protocol=Soap11(), 
) 

但事实并非如此。这将生成以下对象定义:

<xs:complexType name="FooCustomRequest"> 
    <xs:sequence> 
     <xs:element name="Bar" type="s0:Baz" minOccurs="0" nillable="true"/> 
     <xs:element name="Baz" type="xs:string" minOccurs="0" 
        nillable="true"/> 
    </xs:sequence> 
    <xs:attribute name="AttrA" type="xs:string"/> 
    <xs:attribute name="AttrB" type="xs:string"/> 
</xs:complexType> 

正如你看到的,sub_ns声明我们在上面做是Spyne的模式发生器忽略。 <附录> 我的XML是锈迹斑斑,但经过进一步的研究,这似乎是由设计的情况下 - 为xs:element的名称属性不能有一个命名空间前缀(即它是一个NCName),这是不可能的建模您的客户使用Xml Schema技术和朋友向您发送的一种文档。如果你无法说服你的客户发送一个“正确”的请求,那么在这一点上最好的选择就是软验证。 < /编>

所以validator='lxml'绝不会接受您的文档。然而,validator='soft'会,你可以使用它,直到Spyne修复这个bug。

我可以确认下列要求的工作:

<SOAP-ENV:Envelope xmlns:b="www.example.com/schema/b" 
        xmlns:a="www.example.com/schema/a" 
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <soapenv:Body> 
    <a:Foo AttrA="attr-a"> 
     <b:Bar AttrC="attr-c"> 
     <b:Thing>thing</b:Thing> 
     </b:Bar> 
     <a:Baz>baz</a:Baz> 
    </a:Foo> 
    </soapenv:Body> 
</SOAP-ENV:Envelope> 

如果你能在https://github.com/arskom/spyne这种需要产生的XSD片断文件的问题,我可以修复它。

<Addendum2>
我相信,一个模式只能定义在其targetNamespace元素。应该可以通过使用<element ref="b:Baz" />来从另一个命名空间中获得complexType的直接子对象,但这只不过是一个理论。再次,如果您知道需要生成的模式文档类型,请提交问题。否则,软验证的解决方法是目前最好的选择。
< /附录2 >

相关问题