生成用于Salesforce SOAP API的XML

生成用于Salesforce SOAP API的XML,xml,soap,python-requests,lxml,Xml,Soap,Python Requests,Lxml,我已经成功地使用Salesforce REST API一段时间了,但是遇到了一些仅通过SOAP API可用的功能。一个这样的函数是函数。我相信我应该能够使用Salesforce访问令牌(a/k/a会话ID)来调用SOAP API,但是我没有看到一个好的库可以用于此函数以及我感兴趣的其他一些函数 Salesforce在此处提供了一个SOAP请求示例: 我曾尝试编写convertLead()函数,但遇到了一些错误,而且由于我对SOAP和lxml库都是新手,所以我不确定如何诊断 下面是我为生成XML而

我已经成功地使用Salesforce REST API一段时间了,但是遇到了一些仅通过SOAP API可用的功能。一个这样的函数是函数。我相信我应该能够使用Salesforce访问令牌(a/k/a会话ID)来调用SOAP API,但是我没有看到一个好的库可以用于此函数以及我感兴趣的其他一些函数

Salesforce在此处提供了一个SOAP请求示例:

我曾尝试编写convertLead()函数,但遇到了一些错误,而且由于我对SOAP和lxml库都是新手,所以我不确定如何诊断

下面是我为生成XML而编写的类:

from lxml import etree


class SalesforceLeadConverter(object):

    def __init__(self, session_id, lead_id, **kwargs):
        self.session_id = session_id
        self.lead_id = lead_id

    def build_xml(self):
        root = etree.Element(
            "{soapenv}Envelope",
             soapenv='<a rel="nofollow" class="external free" href="http://schemas.xmlsoap.org/soap/envelope/">http://schemas.xmlsoap.org/soap/envelope/</a>',
            urn="urn:enterprise.soap.sforce.com"
            )
        soapenv = etree.SubElement(root, "{soapenv}Header")
        urn = etree.SubElement(soapenv, "{urn}SessionHeader")
        session_id = etree.SubElement(urn, "{urn}sessionId").text=self.session_id
        soapenv2 = etree.SubElement(root, "{soapenv}Body")
        urn2 = etree.SubElement(soapenv2, "{urn}convertLead")
        lead_converts = etree.SubElement(urn2, "{urn}leadConverts")
        lead_id = etree.SubElement(lead_converts, "{urn}leadId").text=self.lead_id

        print(etree.tostring(root, pretty_print=True))
        return root
这将生成以下输出:

 <ns0:Envelope xmlns:ns0="soapenv" urn="urn:enterprise.soap.sforce.com">
    <ns0:Header>
      <ns1:SessionHeader xmlns:ns1="urn">
        <ns1:sessionId>1q2w3e4r...</ns1:sessionId>
      </ns1:SessionHeader>
    </ns0:Header>
    <ns0:Body>
      <ns2:convertLead xmlns:ns2="urn">
        <ns2:leadConverts>
          <ns2:leadId>00Qj000000PMV3h</ns2:leadId>
        </ns2:leadConverts>
      </ns2:convertLead>
    </ns0:Body>
  </ns0:Envelope>
我得到以下错误:

TypeError: data must be a memoryview, buffer or byte string

完整的错误输出在这里:

您正在传递根,根是一个元素对象,您需要返回您正在打印的内容,即etree.tostring(根):


您可能还想更改标题=
{'Content-Type':'text/xml'}

谢谢,这似乎已经解决了这个问题!我又遇到了一个SOAP错误,但是,你知道我做错了什么吗<代码>soapenv:VersionMismatch SOAP请求必须使用SOAP 1.1,未收到作为文档根的SOAP 1.1信封我已为此主题提出了一个新问题:
>>> headers = {'Content-Type':'application/xml', 'SOAPAction':'x'}
>>> requests.post('https://na1.salesforce.com/services/Soap/c/10.0', data=xml, headers=headers)
TypeError: data must be a memoryview, buffer or byte string
def build_xml(self):
        root = etree.Element(
            "{soapenv}Envelope",
            urn="urn:enterprise.soap.sforce.com"
            )
        soapenv = etree.SubElement(root, "{soapenv}Header")
        urn = etree.SubElement(soapenv, "{urn}SessionHeader")
        session_id = etree.SubElement(urn, "{urn}sessionId").text=self.session_id
        soapenv2 = etree.SubElement(root, "{soapenv}Body")
        urn2 = etree.SubElement(soapenv2, "{urn}convertLead")
        lead_converts = etree.SubElement(urn2, "{urn}leadConverts")
        lead_id = etree.SubElement(lead_converts, "{urn}leadId").text=self.lead_id
        return etree.tostring(root)