“SOAP请求必须使用SOAP 1.1 ......”

时间:2016-08-27 16:38:50

标签: xml soap lxml

我正在编写一些生成XML的代码,并使用requests库将XML发布到Salesforce.com的SOAP服务。这是我用来生成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='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 """<?xml version="1.1" encoding="utf-8"?>""" + etree.tostring(root)

然后从shell中,我尝试按如下方式提出请求:

 >>> from myapp.salesforce.soap import SalesforceLeadConverter
 >>> slc = SalesforceLeadConverter(session_id="foo...", lead_id="00Qxkdf...")
 >>> xml = slc.build_xml()
 >>> import requests
 >>> headers = {'Content-Type':'text/xml', 'SOAPAction':'convertLead'}
 >>> out = requests.post('https://na1.salesforce.com/services/Soap/c/10.0', data=xml, headers=headers)

out返回500错误,错误文本返回

  

soapenv:VersionMismatchThe   SOAP请求必须使用SOAP 1.1,没有收到SOAP 1.1 Envelope   该文件   根'

我检查了xml值,即:

'<?xml version="1.0" encoding="utf-8"?><ns0:Envelope xmlns:ns0="soapenv" soapenv="&lt;a rel=&quot;nofollow&quot; class=&quot;external free&quot; href=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&gt;http://schemas.xmlsoap.org/soap/envelope/&lt;/a&gt;" urn="enterprise.soap.sforce.com"><ns0:Header><ns1:SessionHeader xmlns:ns1="urn"><ns1:sessionId>00Dj0000001obaf!AR8AQAvJgjiwkh.BbJa48PB2RZ_ITHBqoZCDa2tf98_6kir5xGBSX4Iz_E7Mt3i_.RwylUoNNEHrrKsyR9huvrxIYoCdUg95</ns1:sessionId></ns1:SessionHeader></ns0:Header><ns0:Body><ns2:convertLead xmlns:ns2="urn"><ns2:leadConverts><ns2:leadId>00Qj000000PMV3h</ns2:leadId><ns2:doNotCreateOpportunity>False</ns2:doNotCreateOpportunity><ns2:sendNotificationEmail>False</ns2:sendNotificationEmail></ns2:leadConverts></ns2:convertLead></ns0:Body></ns0:Envelope>'

我想知道在标题信封中设置为soapenv的HTML编码是否是问题,如果是,我该如何阻止该编码?还有别的我做错了吗?

1 个答案:

答案 0 :(得分:0)

经过漫长的研究过程,我遇到了this post,其中推荐了以下内容:

from lxml import etree

S_NS = 'http://schemas.xmlsoap.org/soap/envelope/'
S_PRE = '{' + S_NS + '}'

env = etree.Element(S_PRE + 'Envelope', nsmap={'soapenv': S_NS})
header = etree.SubElement(env, S_PRE + 'Header')
body = etree.SubElement(env, S_PRE + 'Body')

print(etree.tostring(env, pretty_print=True, encoding='unicode'))