Instantly share code, notes, and snippets.

What would you like to do?
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
import beatbox
import xml.etree.ElementTree as ET
import traceback
import json
__author__ = "Matias Medina"
__date__ = "$11/07/2016 04:02:59 PM$"
class XmlEngine:
# Create a map of attachments by id
def getMapAttachments(self, parentIds, service):
# Query to Salesforce to get the attachments
query_result = service.query("SELECT Id, ParentId, Body FROM Attachment WHERE ParentId IN (" + parentIds + ")")
records = query_result['records']
total_records = query_result['size']
query_locator = query_result['queryLocator']
# Map id to xml string
mapParentIdToXml = {}
# Loop through, pulling the next 500 and appending it to your records dict
while query_result['done'] is False and len(records) < total_records:
query_result = service.queryMore(query_locator)
query_locator = query_result['queryLocator']
records = records + query_result['records']
# Build the map
for att in records:
if att.Body != None:
mapParentIdToXml[att.ParentId] = att.Body.decode('base64')
return mapParentIdToXml
# Read the xml and get the data needed to update Salesforce records
def getDemandSavings(self, xmlStr):
result = ""
node = ""
# Get the root node
root = ET.fromstring(xmlStr)
# Go through the xml nodes to get needed node
for child in root:
if "Project" in child.tag:
for secondChild in child:
if "ProjectDetails" in secondChild.tag:
for thirdChild in secondChild:
if "EnergySavingsInfo" in thirdChild.tag:
for fourthChild in thirdChild:
if "DemandSavings" in fourthChild.tag:
node = fourthChild.text
if node != "":
result = float(node)
print "Malformed XML, missing or invalid DemandSavings"
return result
# Loop through a list of records and update them
def updateObject(self, recordsToUpdate, fieldToUpdate, fieldValue, objectType, service):
updateList = []
for id in recordsToUpdate:
objectUpdate = {"Id": id, fieldToUpdate: fieldValue, "type": objectType}
print "failed"
def runScript(self):
# Initialize the beatbox api to talk to Salesforce
service = beatbox.PythonClient()
# Read credentials to log in Salesforce
with open('settings.json') as data_file:
projectSettings = json.load(data_file)
service.serverUrl = str(projectSettings["SF_SERVER_URL"])
service.login(str(projectSettings["SF_ORG_USER"]), str(projectSettings["SF_ORG_PASSWORD"]))
# The "parentId" needs to be replaced by the id of the record that have attached the xml file
# you can pass a list of string if you want to work with more than one record
xmlByIdMap = self.getMapAttachments("parentId", service);
# Get the attachment stored at the map. Replace "appFileId" with the record id that contains the attachment
# that you you want to parse
xmlString = xmlByIdMap["appFileId"]
# Get the value needed from xml file. This value will be used to update an especific record in Salesforce
demandSavings = self.getDemandSavings(xmlString)
# Replace recordsToUpdate by the list of records to update with the parsed value
# Replace fieldToUpdate by the name of the field that you want to update. Eg: Demand_Savings__c
# Replace objectType by the object that you want to update. Eg: MyCustomObject__c
self.updateObject("recordsToUpdate", "fieldToUpdate", demandSavings, "objectType", service)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment