Spyne:请求输入参数具有不同名称空间

时间:2017-03-03 19:18:36

标签: python soap spyne

我发现了这个问题:https://mail.python.org/pipermail/soap/2013-June/001120.html 我有同样的问题,无法找到答案。请帮忙。

我正在使用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(),
)

谢谢!

1 个答案:

答案 0 :(得分:3)

所以,这是它的工作方式:

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>

如您所见,Spyne的架构生成器会忽略我们上面的sub_ns声明。 的&LT;增编&GT; 我的Xml很生疏,但经过进一步的研究,这似乎是设计的情况 - 因为xs:element的名称属性不能有名称空间前缀(即它&#39; sa NCName),它&# 39;无法使用Xml Schema技术和朋友对客户端发送给您的文档类型进行建模。如果你不能说服你的客户发送&#34;正确的&#34;那么你在这一点上最好的选择是软验证。请求。 &lt; / Addendum&gt;

所以validator='lxml'永远不会接受您的文件。但是,validator='soft'将会使用它,直到在Spyne中修复此错误。

我可以确认以下请求有效:

<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片段的问题,我可以修复它。

&lt;附录2&gt;
我说服架构只能在其targetNamespace中定义元素。应该可以通过使用<element ref="b:Baz" />从另一个名称空间中获得complexType的直接子项,但这只不过是理论。同样,如果您知道需要生成的架构文档类型,请提出问题。否则,软校验的解决方法是您目前最好的选择 &lt; / Addendum2&gt;