I found this question: https://mail.python.org/pipermail/soap/2013-June/001120.html I have the same problem, and can't find an answer. Please help.
I am in the process of implementing some existing WSDL in spyne, and I'm running into a problem where I have requests that contain multiple namespaces. For example, I have a request that looks like:
<?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>
When I send this request, I get the following back:
<?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>
I've been looking at the documentation and setting options, and so far nothing has gotten me past this bump. Is this currently possible with spyne? Do I need to do more and parse the in_document? Any input would be greatly appreciated.
An for more detail the code I've been messing with:
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(),
)
Thanks!
So, here's how it's supposed to work:
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(),
)
But it doesn't. This generates the following object definition:
<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>
As you see, the sub_ns
declaration we make above is ignored by Spyne's schema generator.
<Addendum>
My Xml is rusty but after further research this seems to be the case by design -- as the name attribute of xs:element
can not have a namespace prefix (ie it's a NCName), it's not possible to model the kind of document your client is sending you using the Xml Schema technology and friends. Your best bet at this point is soft validation, if you can't persuade your client to send a "correct" request.
</Addendum>
So validator='lxml'
will never accept your document. However, validator='soft'
will and you can use it until this bug is fixed in Spyne.
I can confirm the following request works:
<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>
If you can file an issue at https://github.com/arskom/spyne with the XSD fragment this needs to generate, I can fix it.
<Addendum2>
I'm persuaded that a schema can only define elements in its targetNamespace
. It should be possible to have immediate children of a complexType from another namespace by using an <element ref="b:Baz" />
but that's nothing more than a theory. Again, if you know the kind of schema document this needs to generate, please file an issue. Otherwise the workaround with soft validation is your best bet at the moment.
</Addendum2>