Регистрация  |  Вход

Парсинг XML и правильное сохранение данных по ExternalID (второй вариант)

Привет Всем. В прошлой статье я рассказал про один из способов как парсить XML в Apex коде. Как оказалось есть способ более интересный по красоте и пониманию.



Возьмем те же данные что нам вернул внешний сервис:




<accounts>
<account>
<id>5234625</id>
<type>Prospect</type>
<industry>Manufacturing</industry>
<employees>680</employees>
</account>
<account>
<id>6327653</id>
<type>Prospect</type>
<industry>Media</industry>
<employees>14688</employees>
</account>
</accounts>


Вот и сам код, которые поможет разобрать этот ответ и красиво обновить записи Account на стороне Salesforce.




List<Account> accountsList = new List<Account>();
DOM.Document doc = new DOM.Document();
doc.load(xmlResponse);
DOM.XMLNode root = doc.getRootElement();
if (root.getNodeType() == DOM.XMLNodeType.ELEMENT && root.getName() == 'Accounts') {
for (Dom.XMLNode child: root.getChildElements()) {
if (child.getNodeType() == DOM.XMLNodeType.ELEMENT && child.getName() == 'Account') {
String extID = child.getChildElement('id', NULL).getText().trim();
String acctype = child.getChildElement('type', NULL).getText().trim();
String industry = child.getChildElement('industry', NULL).getText().trim();
Integer employees = Integer.valueOf(child.getChildElement('employees', NULL).getText().trim());
// кастомные поля в объекте Account взяты просто для примера
accountsList.add(new Account(AccountExternalID__с = extID, AccountType__c = acctype, AccountIndustry = industry, AccountEmployees = employees));
}
}
}

// Магическая строчка - обновление данных в SF
Database.UpsertResult [] ur = Database.upsert(accountsList, Account.Fields.AccountExternalID__с, false);


Для разбора XML я воспользовался замечательным классом DOM.Document, который предоставляет большой набор необходимых инструментов чтобы обойти дерево по ветвям (в отличии от прошлого примера, где XML теги перебирались линейно по всему документу). Ну и в конце магическая строчка - сохранение результатов на стороне Salesforce.



Почему магическая? Она выполняет сразу несколько полезных в этом случае функций:



1. upsert - insert нового account, если до этого accout не существовало или обновление существующего account.



2. Account.Fields.AccountExternalID__c - критерий уникальности для записей account - кастомное поле типа externalID, которое содержит ключи из внешнего сервиса. (по-умолчанию уникальность проверяется по стандартному полю ID)



3. false (третий параметр) - вставлять записи в базу, даже если не все записи валидные. Это особенно актуально, когда данные приходят из внешнего сервиса, а на стороне SF у нас есть куча кастомных валидаторов. (по-умолчанию, если хотя бы одна запись из пачки окажется "битой", то вся пачка не сохранится)



4. Database.UpsertResult [] ur - для особых гурманов :) можно даже обработать результаты сохранения и в случае ошибки найти виновника.



Вот собственно и все :)