SOAP - 必须为元素指定类型属性值

SOAP - Must specify a type attribute value for the element

使用 Python zeep,我正在与 Salesforce 的 SOAP(特别是元数据)交互 API。

尝试 createMetadata 我收到此错误:

Fault: Must specify a {http://www.w3.org/2001/XMLSchema-instance}type attribute value for the {http://soap.sforce.com/2006/04/metadata}metadata element

我收集到这与传递给方法的参数无关(createMetadata 的方式需要一个 metadata 参数,它本身是一个带有 fullName 字段的对象) ,而是关于某处缺少的 xsi:type 属性。

这是我的 zeep 电话:

resp = service['createMetadata'](_soapheaders=soap_headers,
                                 metadata=[{'fullName': 'SomeCustomObject'}])

这是生成的XML:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Body>
    <ns0:createMetadata xmlns:ns0="http://soap.sforce.com/2006/04/metadata">
      <ns0:metadata>
        <ns0:fullName>SomeCustomObject</ns0:fullName>
      </ns0:metadata>
    </ns0:createMetadata>
  </soap-env:Body>
</soap-env:Envelope>

我的问题是:如何使用 zeep?

更新:
我没有使用字典来表示元数据对象,而是将其替换为:

metadata_type = client.get_type('{http://soap.sforce.com/2006/04/metadata}Metadata')
metadata = metadata_type(fullName='SomeCustomObject')
resp = service['createMetadata'](_soapheaders=soap_headers, metadata=[metadata])

新生成的XML是:

<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:Body>
    <ns0:createMetadata xmlns:ns0="http://soap.sforce.com/2006/04/metadata">
      <ns0:metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns0:Metadata">
        <ns0:fullName>SomeCustomObject</ns0:fullName>
      </ns0:metadata>
    </ns0:createMetadata>
  </soap-env:Body>
</soap-env:Envelope>

ns0:metadata 标签上有 xsi:type 属性,但我得到了和以前一样的错误。所以我想这与失踪 xsi:type 无关。有什么想法吗?

这里可以看到xsi定义在metadata.

<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CustomField">
</metadata>

答案是 xsi:type 应该使用 'CustomObject'(或其他合适的类型)而不是 'Metadata',我相信这是 "parent" 类型。这还需要传递的不仅仅是 fullName.

zeep 中表示而不是

metadata_type = client.get_type('{http://soap.sforce.com/2006/04/metadata}Metadata')
metadata = metadata_type(fullName='SomeCustomObject')

我用过

custom_object_type = client.get_type('{http://soap.sforce.com/2006/04/metadata}CustomObject')
custom_object = custom_object_type(fullName='SomeCustomObject__c',
                                   label='SomeCustomObject',
                                   pluralLabel='SomeCustomObjects',
                                   nameField={'label': 'name', 'type': 'Text'},
                                   deploymentStatus='Deployed',
                                   sharingModel='ReadWrite')

然后最后:

resp = service['createMetadata'](_soapheaders=soap_headers,
                                 metadata=[custom_object])