XML格式问题
我是第一次使用Salesforce SOAP API,因此我不熟悉SOAP格式问题等。我使用XML格式问题,xml,soap,lxml,Xml,Soap,Lxml,我是第一次使用Salesforce SOAP API,因此我不熟悉SOAP格式问题等。我使用lxml库生成XML,但似乎存在格式问题 我收到的错误是:“信封元素的子元素必须是Header或Body元素”,这很奇怪,因为当我查看SalesforceLeadConverter.build_XML()方法生成的XML时,它看起来是正确的。这是 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv=
lxml
库生成XML,但似乎存在格式问题
我收到的错误是:“信封元素的子元素必须是Header或Body元素”,这很奇怪,因为当我查看SalesforceLeadConverter.build_XML()方法生成的XML时,它看起来是正确的。这是
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<Header>
<ns0:SessionHeader xmlns:ns0="urn">
<ns0:sessionId>ldfkjskjdfksdfsdfsdf</ns0:sessionId>
</ns0:SessionHeader>
</Header>
<Body>
<ns1:convertLead xmlns:ns1="urn">
<ns1:leadConverts>
<ns1:leadId>00Qj000000PMV3h</ns1:leadId>
<ns1:doNotCreateOpportunity>False</ns1:doNotCreateOpportunity>
<ns1:sendNotificationEmail>False</ns1:sendNotificationEmail>
</ns1:leadConverts>
</ns1:convertLead>
</Body>
</soapenv:Envelope>
LDFKJSKJDFKSDFSFDFF
00Qj000000PMV3h
假的
假的
以下是生成XML的完整类和关联方法:
from lxml import etree
class SalesforceLeadConverter(object):
def __init__(self, session_id, lead_id, **kwargs):
""" Provides functionality for converting a Lead to a new or existing
Account and create a new Contact or update an existing Contact.
account_id: Optional; if specified, converts the Lead to a Contact
associated with this Account.
contact_id: Optional; if specified, converts the Lead into an existing
Contact record, preventing the creation of a duplicate.
"""
self.session_id = session_id
self.lead_id = lead_id
self.account_id = kwargs.get('account_id', False)
self.contact_id = kwargs.get('contact_id', False)
self.converted_status = kwargs.get('converted_status', False)
self.do_not_create_opportunity = str(kwargs.get('do_not_create_opportunity', False))
self.opportunity_name = kwargs.get('opportunity_name', False)
self.owner_id = kwargs.get('owner_id', False)
self.send_notification_email = str(kwargs.get('send_notification_email', False))
def build_xml(self):
S_NS = 'http://schemas.xmlsoap.org/soap/envelope/'
S_PRE = '{' + S_NS + '}'
root = etree.Element(S_PRE + 'Envelope', nsmap={'soapenv': S_NS})
soapenv = etree.SubElement(root, 'Header')
header = etree.SubElement(soapenv, '{urn}SessionHeader')
sid = etree.SubElement(header, '{urn}sessionId').text=self.session_id
soapenv2 = etree.SubElement(root, '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
do_not_create_opportunity = etree.SubElement(
lead_converts,
'{urn}doNotCreateOpportunity'
).text=self.do_not_create_opportunity
send_notification_email = etree.SubElement(
lead_converts,
'{urn}sendNotificationEmail'
).text=self.send_notification_email
xml_meta = """<?xml version="1.1" encoding="utf-8"?>"""
return xml_meta + etree.tostring(root, encoding='utf-8')
从lxml导入etree
类SalesforceLeadConverter(对象):
定义初始(自我、会话id、领导id,**kwargs):
“”“提供将潜在客户转换为新的或现有的潜在客户的功能
帐户并创建新联系人或更新现有联系人。
帐户id:可选;如果指定,则将潜在客户转换为联系人
与此帐户关联。
联系人id:可选;如果指定,则将潜在客户转换为现有客户
联系人记录,防止创建副本。
"""
self.session\u id=session\u id
self.lead\u id=lead\u id
self.account\u id=kwargs.get('account\u id',False)
self.contact\u id=kwargs.get('contact\u id',False)
self.converted_status=kwargs.get('converted_status',False)
self.do_not_create_opportunity=str(kwargs.get('do_not_create_opportunity',False))
self.opportunity\u name=kwargs.get('opportunity\u name',False)
self.owner\u id=kwargs.get('owner\u id',False)
self.send\u notification\u email=str(kwargs.get('send\u notification\u email',False))
def生成xml(自):
苏恩斯http://schemas.xmlsoap.org/soap/envelope/'
S_PRE='{'+S_NS+'}'
root=etree.Element(S_PRE+'Envelope',nsmap={'soapenv':S_NS})
soapenv=etree.SubElement(根,“头”)
header=etree.SubElement(soapenv,{urn}SessionHeader')
sid=etree.SubElement(头,{urn}sessionId')。text=self.session\u id
soapenv2=etree.SubElement(根“Body”)
urn2=etree.SubElement(soapenv2,{urn}convertLead')
lead_converts=etree.SubElement(urn2,{urn}leadConverts')
lead_id=etree.SubElement(
铅的转化,
“{urn}leadId”
).text=self.lead\u id
不创建机会=etree.SubElement(
铅的转化,
“{urn}doNotCreateOpportunity”
).text=self.do\u不创造机会
发送通知电子邮件=etree.SubElement(
铅的转化,
“{urn}发送通知电子邮件”
).text=self.send\u通知\u电子邮件
xml\u元=“”
返回xml_meta+etree.tostring(root,encoding='utf-8')
SOAP正文和标头需要一个命名空间。
此外,以ns0为前缀的元素,ns1也需要一个名称空间声明
因此,您的有效SOAP将是:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="your_namespace_here" xmlns:ns1="your_namespace_here">
<soapenv:Header>
<ns0:SessionHeader xmlns:ns0="urn">
<ns0:sessionId>ldfkjskjdfksdfsdfsdf</ns0:sessionId>
</ns0:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<ns1:convertLead xmlns:ns1="urn">
<ns1:leadConverts>
<ns1:leadId>00Qj000000PMV3h</ns1:leadId>
<ns1:doNotCreateOpportunity>False</ns1:doNotCreateOpportunity>
<ns1:sendNotificationEmail>False</ns1:sendNotificationEmail>
</ns1:leadConverts>
</ns1:convertLead>
</soapenv:Body>
</soapenv:Envelope>
LDFKJSKJDFKSDFSFDFF
00Qj000000PMV3h
假的
假的
SOAP正文和标头需要一个命名空间。
此外,以ns0为前缀的元素,ns1也需要一个名称空间声明
因此,您的有效SOAP将是:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="your_namespace_here" xmlns:ns1="your_namespace_here">
<soapenv:Header>
<ns0:SessionHeader xmlns:ns0="urn">
<ns0:sessionId>ldfkjskjdfksdfsdfsdf</ns0:sessionId>
</ns0:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<ns1:convertLead xmlns:ns1="urn">
<ns1:leadConverts>
<ns1:leadId>00Qj000000PMV3h</ns1:leadId>
<ns1:doNotCreateOpportunity>False</ns1:doNotCreateOpportunity>
<ns1:sendNotificationEmail>False</ns1:sendNotificationEmail>
</ns1:leadConverts>
</ns1:convertLead>
</soapenv:Body>
</soapenv:Envelope>
LDFKJSKJDFKSDFSFDFF
00Qj000000PMV3h
假的
假的
下面修改的SalesforceLeadConverter类解决了标题/正文名称空间问题(MGorgon为我指明了正确的方向,对此我表示感谢)。最终引导我找到正确的解决方案
请注意,虽然名称空间问题已得到解决,但下面的代码仍然不起作用……出现了另一个问题,我得到了以下错误:
“没有可用于请求{enterprise.soap.sforce.com}convertLead的操作”
总之,这是我的soap.py文件:
import requests
from lxml.etree import Element, SubElement, tostring
class SalesforceLeadConverter(object):
def __init__(self, session_id, lead_id, **kwargs):
""" Provides functionality for converting a Lead to a new or existing
Account and create a new Contact or update an existing Contact.
account_id: Optional; if specified, converts the Lead to a Contact
associated with this Account.
contact_id: Optional; if specified, converts the Lead into an existing
Contact record, preventing the creation of a duplicate.
"""
self.session_id = session_id
self.lead_id = lead_id
self.account_id = kwargs.get('account_id', False)
self.contact_id = kwargs.get('contact_id', False)
self.converted_status = kwargs.get('converted_status', False)
self.do_not_create_opportunity = str(kwargs.get('do_not_create_opportunity', False))
self.opportunity_name = kwargs.get('opportunity_name', False)
self.owner_id = kwargs.get('owner_id', False)
self.send_notification_email = str(kwargs.get('send_notification_email', False))
def build_xml(self):
schema_ns = 'http://schemas.xmlsoap.org/soap/envelope/'
urn_ns = 'enterprise.soap.sforce.com'
S_PRE = '{' + schema_ns + '}'
envelope = Element(
S_PRE + 'Envelope',
nsmap={'soapenv': schema_ns, 'urn': urn_ns}
)
header = SubElement(envelope, '{%s}Header' % schema_ns)
s_header = SubElement(header, '{%s}SessionHeader' % urn_ns)
sid = SubElement(s_header, '{%s}sessionId' % urn_ns).text=self.session_id
body = SubElement(envelope, '{%s}Body' % schema_ns)
convert_lead = SubElement(body, '{%s}convertLead' % urn_ns)
lead_converts = SubElement(convert_lead, '{%s}leadConverts' % urn_ns)
lead_id = SubElement(
lead_converts,
'{%s}leadId' % urn_ns
).text=self.lead_id
do_not_create_opportunity = SubElement(
lead_converts,
'{%s}doNotCreateOpportunity' % urn_ns
).text=self.do_not_create_opportunity
send_notification_email = SubElement(
lead_converts,
'{%s}sendNotificationEmail' % urn_ns
).text=self.send_notification_email
if self.account_id:
account_id = SubElement(
lead_converts,
'{%s}accountId' % urn_ns
).text=self.account_id
if self.contact_id:
contact_id = SubElement(
lead_converts,
'{%s}contactId' % urn_ns
).text=self.contact_id
if self.converted_status:
converted_status = SubElement(
lead_converts,
'{%s}convertedStatus' % urn_ns
).text=self.converted_status
xml_meta = """<?xml version="1.1" encoding="utf-8"?>"""
return xml_meta + tostring(envelope, encoding='utf-8')
def post(self):
xml = self.build_xml()
headers = {'Content-Type':'text/xml', 'SOAPAction':'convertLead'}
url = 'https://na1.salesforce.com/services/Soap/u/34.0'
out = requests.post(url, data=xml, headers=headers)
return out, out.text
导入请求
从lxml.etree导入元素、子元素到字符串
类SalesforceLeadConverter(对象):
定义初始(自我、会话id、领导id,**kwargs):
“”“提供将潜在客户转换为新的或现有的潜在客户的功能
帐户并创建新联系人或更新现有联系人。
帐户id:可选;如果指定,则将潜在客户转换为联系人
与此帐户关联。
联系人id:可选;如果指定,则将潜在客户转换为现有客户
联系人记录,防止创建副本。
"""
self.session\u id=session\u id
self.lead\u id=lead\u id
self.account\u id=kwargs.get('account\u id',False)
self.contact\u id=kwargs.get('contact\u id',False)
self.converted_status=kwargs.get('converted_status',False)
self.do_not_create_opportunity=str(kwargs.get('do_not_create_opportunity',False))
self.opportunity\u name=kwargs.get('opportunity\u name',False)
self.owner\u id=kwargs.get('owner\u id',False)
self.send\u notification\u email=str(kwargs.get('send\u notification\u email',False))
def生成xml(自):
模式http://schemas.xmlsoap.org/soap/envelope/'
urn_ns='enterprise.soap.sforce.com'
S_PRE='{'+schema_ns+'}'
包络线=元素(
S_PRE+“信封”,
nsmap={'soapenv':模式“'urn':urn}
)
header=子元素(信封,{%s}头“%schema\n”
s_header=子元素(头,{%s}会话头'%urn_ns)
sid=子元素(s_头,{%s}会话id'%urn_ns)。text=self.session_id
body=子元素(信封,{%s}正文“%schema\n”
convert_lead=子元素(主体,{%s}convertLead'%urn_ns)
前导转换=子元素(转换)