首页 > 解决方案 > 在 Python 中解析 Salesforce.com XML 消息

问题描述

我正在尝试连接 Python 和 Salesforce。

Salesforce 向我发送了一条出站 SOAP 消息,我正确接收、确认并阅读了该消息。

现在,我想解析消息以确定要在 Python 中触发的脚本。

以下是收到的消息正文的打印示例:(我已将 ID 匿名化为 XXX)

b'<?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>00Dxxxx</OrganizationId>
   <ActionId>04k5A000000XXX</ActionId>
   <SessionId xsi:nil="true"/>
   <EnterpriseUrl>https://xxx-dev-ed.my.salesforce.com/services/Soap/c/45.0/00Dxxxx </EnterpriseUrl>
   <PartnerUrl>https://xxx-dev-ed.my.salesforce.com/services/Soap/u/45.0/00Dxxxx </PartnerUrl>
   <Notification>
    <Id>04l5A000XXX</Id>
    <sObject xsi:type="sf:QuoteHistory__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>a0B5A0XXX</sf:Id>
     <sf:Status__c>Send price request</sf:Status__c>
    </sObject>
   </Notification>
  </notifications>
 </soapenv:Body>
</soapenv:Envelope>'

str 前面的 b 是什么?当我打印消息正文时,Python 会打印它。它有什么影响吗?

现在,要处理我的消息,我想阅读 sObject 选项卡中的行,即我的示例中的那些:

    <sObject xsi:type="sf:QuoteHistory__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>a0B5A0XXX</sf:Id>
     <sf:Status__c>Send price request</sf:Status__c>
    </sObject>

有时,我希望我的消息发送除 Status 和 Id 之外的其他字段,并且我想将消息正确解析到表中,然后根据发送的字段及其值确定要触发的操作。

我将在我身边管理一个包含字段名称/字段值和触发操作的表格,这对我来说似乎很容易。

正确和动态地阅读此消息的最佳方法是什么?

标签: pythonxmlsoapsalesforce

解决方案


看看下面

import re
import xml.etree.ElementTree as ET

XML = '''<?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>00Dxxxx</OrganizationId>
   <ActionId>04k5A000000XXX</ActionId>
   <SessionId xsi:nil="true"/>
   <EnterpriseUrl>https://xxx-dev-ed.my.salesforce.com/services/Soap/c/45.0/00Dxxxx </EnterpriseUrl>
   <PartnerUrl>https://xxx-dev-ed.my.salesforce.com/services/Soap/u/45.0/00Dxxxx </PartnerUrl>
   <Notification>
    <Id>04l5A000XXX</Id>
    <sObject xsi:type="sf:QuoteHistory__c" xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
     <sf:Id>a0B5A0XXX</sf:Id>
     <sf:Status__c>Send price request</sf:Status__c>
    </sObject>
   </Notification>
  </notifications>
 </soapenv:Body>
</soapenv:Envelope>'''

_xml = xmlstring = re.sub(' xmlns="[^"]+"', '', XML, count=1)
tree = ET.fromstring(_xml)
sobject = tree.find('.//sObject')
for idx, child in enumerate(list(sobject)):
    print('{}) {} => {}'.format(idx, child.tag[child.tag.find('}') + 1:], child.text))

输出

0) Id => a0B5A0XXX
1) Status__c => Send price request

推荐阅读