xsi:type 属性未解析为类型定义

xsi:type attribute does not resolve to a type definition

你们知道如何解决吗?我试图将 type_name 作为 Lead,但它也没有用。

xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/">soap11env:Bodysoap11env:Faultsoap11env:Client.SchemaValidationError:1:0:ERROR:SCHEMASV:SCHEMAV_CVC_ELT_4_2: Element '{http://soap.sforce.com/2005/09/outbound}sObject', attribute '{http://www.w3.org/2001/XMLSchema-instance}type': The QName value '{urn:sobject.enterprise.soap.sforce.com}Lead' of the xsi:type attribute does not resolve to a type definition.</soap11env:Fault></soap11env:Body></soap11env:Envelope>%

我的代码:

import logging
from spyne.model.primitive import Unicode, String, Integer64
from spyne.model.complex import ComplexModel
from spyne.service import ServiceBase
from spyne.decorator import rpc

class SObjectType(ComplexModel):
    __namespace__ = 'urn:sobject.enterprise.soap.sforce.com'
    __type_name__ = 'sObject'
    Id = String
    Company_ID__C = Integer64
    Company_Size_Text__c = Unicode

class NotificationType(ComplexModel):
    Id = Unicode
    sObject = SObjectType

class notificationsType(ComplexModel):
    __namespace__ = 'http://soap.sforce.com/2005/09/outbound'
    __type_name__ = 'notifications'
    OrganizationId = Unicode
    ActionId = Unicode
    SessionId = String(nillable="true")
    Notification = NotificationType.customize(max_occurs='100')

class SomeService(ServiceBase):

    @rpc(notificationsType)
    def MyMethod(ctx, notificationsType):
        print(notificationsType)

if __name__ == '__main__':
    from spyne.application import Application
    from spyne.protocol.soap import Soap11
    from spyne.server.wsgi import WsgiApplication
    from wsgiref.simple_server import make_server

    logging.basicConfig(level=logging.DEBUG)
    logging.info('listening to http://127.0.0.1:8080')

    application = Application([SomeService],
                          tns='http://soap.sforce.com/2005/09/outbound',
                          in_protocol=Soap11(validator='lxml'),
                          out_protocol=Soap11())

    wsgi_application = WsgiApplication(application)
    server = make_server('127.0.0.1', 8080, wsgi_application)
    server.serve_forever()

这是请求:

curl --header "Content-Type: text/xml" --data @"/home/sample_request.xml" "http://127.0.0.1:8080/?wsdl"

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
   <OrganizationId>082342234242</OrganizationId>
   <ActionId>3432342DFSFDf343</ActionId>
   <SessionId xsi:nil="true"/>
   <Notification>
    <Id>34FG23234343irKYQAY</Id>
    <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>00Q4100000vNZBlEAO</sf:Id>
     <sf:Company_ID__C>4203320</sf:Company_ID__C>
     <sf:Company_Size_Text__c>501-1,000</sf:Company_Size_Text__c>
    </sObject>
   </Notification>
   <Notification>
    <Id>6565ffd45eewwe322323</Id>
    <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>3453453453453</sf:Id>
     <sf:Company_ID__C>4556456</sf:Company_ID__C>
     <sf:Company_Size_Text__c></sf:Company_Size_Text__c>
    </sObject>
   </Notification>
  </notifications>
 </soapenv:Body>
</soapenv:Envelope>

除了我已经在此处尝试向您解释的内容之外,还有此答案:https://github.com/arskom/spyne/discussions/686

您的服务定义有误。根据您的要求文件,您需要的是:

class SomeService(ServiceBase):
    __tns__ = 'http://soap.sforce.com/2005/09/outbound'

    @rpc(sObject)
    def MyMethod(ctx, mymethodparam):
        print(mymethodparam)

至于你得到的错误,其实很清楚:

QName value '{urn:sobject.enterprise.soap.sforce.com}Lead' of the xsi:type attribute does not resolve to a type definition

您需要在“urn:sobject.enterprise.soap.sforce.com”命名空间中有一个名为“Lead”的对象。

以下片段暗示这是一个多态请求:

    <sObject xsi:type="sf:Lead" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">

要解析多态请求,您首先需要通过将 polymorphic=True 传递给入站协议实例来启用它们。

然后,您需要定义您的系统将接受的所有可能类型。

在这种情况下,您至少需要 Lead 对象的定义。

class SObjectType(ComplexModel):
    __namespace__ = 'urn:sobject.enterprise.soap.sforce.com'
    __type_name__ = 'sObject'
    Id = String
    Company_ID__C = Integer64
    Company_Size_Text__c = Unicode


class Lead(SObjectType):
    __namespace__ = "urn:sobject.enterprise.soap.sforce.com"

    lead_field = Unicode

    # (...)
    # any additional fields that the lead object might have

据我所知,要将一种类型注册为子类,它的定义中必须至少有一个属于自己的字段(这可能是错误或功能,具体取决于您问的是谁)

因此,如果 Lead 对象没有其他字段,您无论如何都需要在其定义中至少包含一个字段(在本例中称为 lead_field)。只要您的代码不使用它,它就无害。但是,如果潜在客户定义中已有其他字段,则不必再添加。

成功了!这是最终的解决方案。

NS_C = "urn:sobject.enterprise.soap.sforce.com"

class sObjectType(ComplexModel):
    __namespace__ = NS_C
    Id = Unicode
    Company_ID__C = Integer64
    Company_Size_Text__c = String

class Lead(sObjectType):
    lead_field = Unicode
     
class NotificationType(ComplexModel):
    Id = Unicode
    sObject = sObjectType

NS_B = "http://soap.sforce.com/2005/09/outbound"

class OutboundMessagingService(ServiceBase):
    __namespace__ = NS_B
    @srpc(Unicode, NotificationType, sObjectType, _returns=notificationsResponseReturn)
    def notifications(tctx, Notification, sObject):
##. Do things here. 
application = Application([OutboundMessagingService], 
                            tns='http://soap.sforce.com/2005/09/outbound',
                            in_protocol=Soap11(),
                            out_protocol=Soap11())

wsgi_application = WsgiApplication(application)

谢谢布拉克!