Разобрать Salesforce.com XML-сообщение в Python - PullRequest
0 голосов
/ 02 июня 2019

Я пытаюсь связать Python и Salesforce.

Salesforce отправляет мне исходящее SOAP-сообщение, которое я правильно получаю, подтверждаю и читаю.

Теперь я хотел бы проанализировать сообщение, чтобы определить, какой скрипт вызывать в Python.

Ниже приведен печатный пример тела полученного сообщения: (У меня есть анонимные идентификаторы с 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>'

Что такое б перед ул? 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, и я хотел бы правильно проанализировать сообщение в таблице, а затем определить, какое действие инициировать, на основе отправленных полей и их значений.

Со своей стороны я буду управлять таблицей с именами полей / значениями полей и действием для запуска, что мне кажется простым.

Как лучше всего правильно и динамически прочитать это сообщение?

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Посмотрите ниже

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
0 голосов
/ 04 июня 2019

нашел свой путь, используя xmltodict

import pandas as pd 
import xmltodict

#Convert the msg to dict
ParsedSFMessage = xmltodict.parse(sfmsg)
#Keep only the needed level
ParsedSFMessage = ParsedSFMessage['soapenv:Envelope']['soapenv:Body']['notifications']['Notification']['sObject'] 
#Convert to df and transpose
ParsedSFMessage = pd.DataFrame.from_dict(ParsedSFMessage, orient='index').T.drop(columns = ['@xmlns:sf'])

Et voilà

@xsi:type   sf:Id   sf:Status__c
sf:QuoteHistory__c  a0B5A0XXXX  Send price request
...