2017-03-03 34 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 >

相關問題