+ Start a Discussion
ismyhcismyhc 

Help parsing xml and inserting its values into custom object

Hey Guys,

 

Im struggling abit with figuring out how to parse some xml into a custom object. Ive been working with the xmlstreamreader example, but I cant quite wrap my head around how step through the xml elements values that I want to insert into my custom object....

 

The xml response Im getting back from my webcallout looks like this:

 

<advertisers type="array">
  <advertiser>
    <id type="integer">7</id>
    <name>ABC Telecom</name>
  </advertiser>
  <advertiser>
    <id type="integer">106</id>
    <name>ABC_Ozone</name>
  </advertiser><advertiser>
    <id type="integer">13</id>
    <name>Acme Corp</name>
  </advertiser>
</advertisers>

 

My goal is loop through this and extract the value of id and name of each advertiser. I would then like to insert the id and name of each advertiser into a custom object. I would use the name field for the name of the advertiser and I have a custom field realationship setup to store the id value.

 

Any help is much appreciated.

Best Answer chosen by Admin (Salesforce Developers) 
BritishBoyinDCBritishBoyinDC

Can't guarantee this is the most efficient way to do it, but using Account as an example, here's how you could parse that XML and create a list of Accounts to insert/upsert. I included the XML string so you can test it in the system console, but if you're getting it back from the web callout, you should be able to just set docx to the result and parse it from there...

 

String s = '<advertisers type="array">' +
'<advertiser>   <id type="integer">7</id>  <name>ABC Telecom</name>   </advertiser> ' +
'<advertiser>   <id type="integer">106</id>  <name>ABC_Ozone</name>  </advertiser> ' +
'<advertiser>   <id type="integer">13</id>   <name>Acme Corp</name>  </advertiser> ' + 
'</advertisers> ';

List<Account> newaccounts = new List<Account> ();

Dom.Document docx = new Dom.Document();
docx.load(s);
dom.XmlNode xroot = docx.getrootelement() ;

dom.XmlNode [] xrec = xroot.getchildelements() ; //Get all Record Elements

for(Dom.XMLNode child : xrec) //Loop Through Records
{
 account a = new Account ();

  for (dom.XmlNode awr : child.getchildren() ) {
                         if (awr.getname() == 'id') {
                               system.debug('Id' + awr.gettext());
                               a.accountnumber = awr.gettext();
 }  
      
                         if (awr.getname() == 'name') {
                               system.debug('name' + awr.gettext());
                               a.name = awr.gettext();
 }  


}
newaccounts.add(a);
}
system.debug(newaccounts);//you could insert here or upsert based on ID with an external Id field

 

All Answers

BritishBoyinDCBritishBoyinDC

Can't guarantee this is the most efficient way to do it, but using Account as an example, here's how you could parse that XML and create a list of Accounts to insert/upsert. I included the XML string so you can test it in the system console, but if you're getting it back from the web callout, you should be able to just set docx to the result and parse it from there...

 

String s = '<advertisers type="array">' +
'<advertiser>   <id type="integer">7</id>  <name>ABC Telecom</name>   </advertiser> ' +
'<advertiser>   <id type="integer">106</id>  <name>ABC_Ozone</name>  </advertiser> ' +
'<advertiser>   <id type="integer">13</id>   <name>Acme Corp</name>  </advertiser> ' + 
'</advertisers> ';

List<Account> newaccounts = new List<Account> ();

Dom.Document docx = new Dom.Document();
docx.load(s);
dom.XmlNode xroot = docx.getrootelement() ;

dom.XmlNode [] xrec = xroot.getchildelements() ; //Get all Record Elements

for(Dom.XMLNode child : xrec) //Loop Through Records
{
 account a = new Account ();

  for (dom.XmlNode awr : child.getchildren() ) {
                         if (awr.getname() == 'id') {
                               system.debug('Id' + awr.gettext());
                               a.accountnumber = awr.gettext();
 }  
      
                         if (awr.getname() == 'name') {
                               system.debug('name' + awr.gettext());
                               a.name = awr.gettext();
 }  


}
newaccounts.add(a);
}
system.debug(newaccounts);//you could insert here or upsert based on ID with an external Id field

 

This was selected as the best answer
ismyhcismyhc

This was great help!

 

Thanks!!!

nagalakshminagalakshmi

Hi,

 

I am trying to integrate the mail chimp with salesforce. For this i have wrote the http callouts. I am getting the result in xml. But the xml result having more than one elements. How can i parse this and how can i display all fields in vf page.

 I have tried the code which you have sent but i am getting nulls in the list... Please help me...

I have wrote the program like this.

public class mailchimp1
{
public string body1{set;get;}
String from_name;
String from_email;
public void detail()
{
Http h = new Http();
HttpRequest req = new HttpRequest();
final string username = 'xxxxxx';
final string password = 'xxxxx';
Blob headerValue = Blob.valueOf(username + ':' + password);
String authorizationHeader = 'BASIC ' +EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization',authorizationHeader);
//req.setHeader('Content-length', '1753' );
req.setHeader('Host','http://us5.api.mailchimp.com/1.3/ ');
req.setHeader('Connection','keep-alive');
req.setHeader('Content-Type', 'application/xml;charset=UTF-8');
req.setMethod('GET');
//req.setbody('http://api.createsend.com/api/v3/clients.xml');
//req.setEndpoint('http://us5.api.mailchimp.com/1.3/ ');
req.setEndpoint('http://us5.api.mailchimp.com/1.3/?output=xml&method=campaigns&apikey=eb7d2ec8ba15120cc1115c44d32a35c...
HttpResponse res = h.send(req);
system.debug('********'+res.getbody());
body1=res.getbody();
Dom.Document doc = res.getBodyDocument();
//Retrieve the root element for this document.
Dom.XMLNode address = doc.getRootElement();
from_name= address.getChildElement('from_name',from_name).getText();
from_email = address.getChildElement('from_email',from_email).getText();
 // print out specific elements
    
        System.debug('Name== ' + from_name);
        System.debug('email=== ' + from_email);
        
        // Alternatively, loop through the child elements.
    
        // This prints out all the elements of the address
    
        for(Dom.XMLNode child : address.getChildElements()) {
           System.debug('c==='+child.getText());
        }
}
}

 

I am getting the result as

<MCAPI type="array">
<total type="integer">21</total>
<data type="array">
<struct key="0" type="array">
<id type="string">5bef810a37</id>
<web_id type="double">94233</web_id>
<list_id type="string">90cdce872a</list_id>
<folder_id type="double">0</folder_id>
<template_id type="double">0</template_id>
<content_type type="string">html</content_type>
<title type="string">testvf</title>
<type type="string">regular</type>
<create_time type="string">2012-09-07 10:09:42</create_time>
<send_time type="NULL" />
<status type="string">save</status>
<from_name type="string">lakshmi</from_name>
<from_email type="string">nagalakshmi_b@dskvap.com</from_email>
<subject type="string">testvf</subject>
<to_name type="string">lakshmi</to_name>
<archive_url type="string">http://eepurl.com/psBDz</archive_url>
<emails_sent type="integer">0</emails_sent>
<inline_css type="boolean" />
<analytics type="string">N</analytics>
<analytics_tag type="string" />
<authenticate type="boolean" />
<ecomm360 type="boolean" />
<auto_tweet type="boolean" />
<auto_fb_post type="string" />
<auto_footer type="boolean" />
<timewarp type="boolean" />
<timewarp_schedule type="NULL" />
<tracking type="array">
<html_clicks type="boolean">1</html_clicks>
<text_clicks type="boolean">1</text_clicks>
<opens type="boolean">1</opens>
</tracking>
<segment_text type="string">No segment used</segment_text>
<segment_opts type="array" />
<type_opts type="array" />
</struct>
<struct key="3" type="array">
<id type="string">69c9dd75ee</id>
<web_id type="double">93077</web_id>
<list_id type="string">90cdce872a</list_id>
<folder_id type="double">0</folder_id>
<template_id type="double">0</template_id>
<content_type type="string">html</content_type>
<title type="string">campaignthroughform</title>
<type type="string">regular</type>
<create_time type="string">2012-09-06 12:34:28</create_time>
<send_time type="NULL" />
<status type="string">save</status>
<from_name type="string">lakshmi</from_name>
<from_email type="string">nagalakshmi_b@dskvap.com</from_email>
<subject type="string">campaignthroughform</subject>
<to_name type="string">naga</to_name>
<archive_url type="string">http://eepurl.com/pdzrz</archive_url>
<emails_sent type="integer">0</emails_sent>
<inline_css type="boolean" />
<analytics type="string">N</analytics>
<analytics_tag type="string" />
<authenticate type="boolean" />
<ecomm360 type="boolean" />
<auto_tweet type="boolean" />
<auto_fb_post type="string" />
<auto_footer type="boolean" />
<timewarp type="boolean" />
<timewarp_schedule type="NULL" />
<tracking type="array">
<html_clicks type="boolean">1</html_clicks>
<text_clicks type="boolean">1</text_clicks>
<opens type="boolean">1</opens>
</tracking>
<segment_text type="string">No segment used</segment_text>
<segment_opts type="array" />
<type_opts type="array" />
</struct>
<struct key="4" type="array">
<id type="string">45d150a7e8</id>
<web_id type="double">93069</web_id>
<list_id type="string">90cdce872a</list_id>
<folder_id type="double">0</folder_id>
<template_id type="double">0</template_id>
<content_type type="string">html</content_type>
<title type="string">samplecamapign</title>
<type type="string">regular</type>
<create_time type="string">2012-09-06 12:29:16</create_time>
<send_time type="NULL" />
<status type="string">save</status>
<from_name type="string">lakshmi</from_name>
<from_email type="string">nagalakshmi_b@dskvap.com</from_email>
<subject type="string">samplecamapign</subject>
<to_name type="string">naga</to_name>
<archive_url type="string">http://eepurl.com/pdzrD</archive_url>
<emails_sent type="integer">0</emails_sent>
<inline_css type="boolean" />
<analytics type="string">N</analytics>
<analytics_tag type="string" />
<authenticate type="boolean" />
<ecomm360 type="boolean" />
<auto_tweet type="boolean" />
<auto_fb_post type="string" />
<auto_footer type="boolean" />
<timewarp type="boolean" />
<timewarp_schedule type="NULL" />
<tracking type="array">
<html_clicks type="boolean">1</html_clicks>
<text_clicks type="boolean">1</text_clicks>
<opens type="boolean">1</opens>
</tracking>
<segment_text type="string">No segment used</segment_text>
<segment_opts type="array" />
<type_opts type="array" />
</struct>
</data>
</MCAPI>

When i am executing the above code i am getting error as 'Attempt to de-reference a null object' . Please any one help me.

 

Thanks,

Lakshmi

BritishBoyinDCBritishBoyinDC

There's something odd with that XML - the nodes seem to be returned with text AND as null - not sure why to honest, but if you add a null check, it does work okay...

 

List<String> sNames = new List<String> ();

Dom.Document docx = new Dom.Document();
            docx.load(XMLstring);
           
            dom.XmlNode xroot = docx.getrootelement() ;
            dom.XmlNode xdata = xroot.getchildelement('data',null) ; //
            dom.XmlNode [] xdatalist = xdata.getchildren();

for (dom.XmlNode xrloop: xdatalist) {

    if (xrloop.getchildelement('from_name', null) != null) {
            if (xrloop.getchildelement('from_name', null).gettext() != null) {
               sNames.add(xrloop.getchildelement('from_name', null).gettext());
        }
}

if (xrloop.getchildelement('from_email', null) != null) {
            if (xrloop.getchildelement('from_email', null).gettext() != null) {
               sNames.add(xrloop.getchildelement('from_email', null).gettext());
        }
}


}
system.debug(sNames);

 

pankaj kabrapankaj kabra

great work :-)

SF Beginner 2019SF Beginner 2019
how to debug this?
SF Beginner 2019SF Beginner 2019
I tried something like these.

public with sharing class xmltosobject{
    public string s='';
    public void readxml(ID TestObjectID){
        XmlParsed__c TObj = [SELECT XMl__c FROM XmlParsed__c where id= : TestObjectID];
        s= TObj.Event_Message_XML__c ;
        List<Account> newaccounts = new List<Account> ();
        
        Dom.Document docx = new Dom.Document();
        docx.load(s);
        dom.XmlNode xroot = docx.getrootelement() ;
        
        dom.XmlNode [] xrec = xroot.getchildelements() ; //Get all Record Elements
        
        for(Dom.XMLNode child : xrec) //Loop Through Records
        {
            account a = new Account ();
            
            for (dom.XmlNode awr : child.getchildren() ) {
                if (awr.getname() == 'id') {
                    system.debug('Id' + awr.gettext());
                    a.accountnumber = awr.gettext();
                }  
                
                if (awr.getname() == 'name') {
                    system.debug('name' + awr.gettext());
                    a.name = awr.gettext();
                }  
                
                
            }
            newaccounts.add(a);
        }
        system.debug(newaccounts);//you could insert here or upsert based on ID with an external Id field
    }
}