function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Bryan TelfordBryan Telford 

Parsing through repeating XML elements

Assume I have the following section of xml. I need to parse each individual _CreditScore attribute for each BORROWER/_CREDIT_SCORE/_CREDIT_SCORE

<BORROWER BorrowerID="B11467282">
    <_CREDIT_SCORE> 
        <_CREDIT_SCORE _CreditScore="691" _ReportingAgency="Experian" /> 
        <_CREDIT_SCORE _CreditScore="695" _ReportingAgency="TransUnion" /> 
        <_CREDIT_SCORE _CreditScore="678" _ReportingAgency="Equifax" /> 
    </_CREDIT_SCORE> 
</BORROWER> 
<BORROWER BorrowerID="B11467439" 
    <_CREDIT_SCORE> 
        <_CREDIT_SCORE _CreditScore="685" _ReportingAgency="Experian" /> 
        <_CREDIT_SCORE _CreditScore="681" _ReportingAgency="TransUnion" /> 
        <_CREDIT_SCORE _CreditScore="684" _ReportingAgency="Equifax" /> 
    </_CREDIT_SCORE> 
</BORROWER>

Using the below code, I would have thought it would loop through both BORROWER elements and each /BORROWER/_CREDIT_SCORE/_CREDIT_SCORE section.

However, the result is that it only loops twice through the first /BORROWER/_CREDIT_SCORE/_CREDIT_SCORE, so I end up with the same value twice in my debug log.

Actual Result: 14:23:13.143 (1156222554)|USER_DEBUG|[179]|DEBUG|Experian: (691, 691)
Expected Result: 14:23:13.143 (1156222554)|USER_DEBUG|[179]|DEBUG|Experian: (691, 685)

Here is the parsing logic.

List<String> Experian = new List<String>();
List<String> Equifax = new List<String>();    
List<String> Transunion = new List<String>();        

for (Dom.XmlNode node : doc.getRootElement().getChildElement('_APPLICATION', null).getChildElement('BORROWER', null).getChildElement('_CREDIT_SCORE', null).getChildElements()) {
                 if(node.getAttributeValue('_ReportingAgency','')=='Experian')  {
                    Experian.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Experian: ' + Experian);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='Equifax') {
                    Equifax.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Equifax: ' + Equifax);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='TransUnion') {
                    Transunion.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('TransUnion: ' + Transunion);                    
                 }

For reference, here is the logic for inserting the data.
   for(Integer i = 1; i <= experian.size(); i++) {
                lockdata.put('NYLX_Experian_Score_'+i+'__c', integer.valueof(Experian.get(i-1)));
             } 
             
             for(Integer i = 1; i <= equifax.size(); i++) {
                lockdata.put('NYLX_Equifax_Score_'+i+'__c', integer.valueof(Equifax.get(i-1)));
             } 
             for(Integer i = 1; i <= transunion.size(); i++) {
                lockdata.put('NYLX_TransUnion_Score_'+i+'__c', integer.valueof(Transunion.get(i-1)));
             }

Thanks for any help!
Best Answer chosen by Bryan Telford
Bryan TelfordBryan Telford
Hi Naval,

Thanks for your posts. Using your first response I was able to solve the issue. I just needed to add an extra "if" statement. The final code looks like this. The bolded part is what I added to get this working.  Thanks again for your help.

for (Dom.XmlNode rootNode : doc.getRootElement().getChildElement('_APPLICATION', null).getChildElements()) {
             if(rootNode.getName() =='BORROWER') {
             for(Dom.XmlNode node : rootNode.getChildElement('_CREDIT_SCORE', null).getChildElements()){
                 if(node.getAttributeValue('_ReportingAgency','')=='Experian')  {
                    Experian.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Experian: ' + Experian);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='Equifax') {
                    Equifax.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Equifax: ' + Equifax);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='TransUnion') {
                    Transunion.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('TransUnion: ' + Transunion);                    
                 }
                 }
              }
              
             }

All Answers

Naval Sharma4Naval Sharma4
Hey,

Use the following code snippet.
 
for (Dom.XmlNode rootNode : doc.getRootElement().getChildElement('_APPLICATION', null).getChildElements()) {
     for(Dom.XmlNode node : rootNode.getChildElement('_CREDIT_SCORE', null).getChildElements()){
                 if(node.getAttributeValue('_ReportingAgency','')=='Experian')  {
                    Experian.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Experian: ' + Experian);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='Equifax') {
                    Equifax.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Equifax: ' + Equifax);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='TransUnion') {
                    Transunion.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('TransUnion: ' + Transunion);                    
                 }
​     }
}

 
Bryan TelfordBryan Telford
Hi there,

Thanks for your reply! I tried the above code, but I get the following error.
15:44:44.98 (1120594914)|FATAL_ERROR|System.NullPointerException: Attempt to de-reference a null object

The debug log throws that error at this line:
for(Dom.XmlNode node : rootNode.getChildElement('_CREDIT_SCORE', null).getChildElements()){

 
Naval Sharma4Naval Sharma4
Hi Brayan,

Refer this link as this is very explainable.
https://www.sundoginteractive.com/blog/parsing-xml-in-salesforce-apex
Bryan TelfordBryan Telford
Hi Naval,

Thanks for your posts. Using your first response I was able to solve the issue. I just needed to add an extra "if" statement. The final code looks like this. The bolded part is what I added to get this working.  Thanks again for your help.

for (Dom.XmlNode rootNode : doc.getRootElement().getChildElement('_APPLICATION', null).getChildElements()) {
             if(rootNode.getName() =='BORROWER') {
             for(Dom.XmlNode node : rootNode.getChildElement('_CREDIT_SCORE', null).getChildElements()){
                 if(node.getAttributeValue('_ReportingAgency','')=='Experian')  {
                    Experian.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Experian: ' + Experian);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='Equifax') {
                    Equifax.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('Equifax: ' + Equifax);
                 }
                 if(node.getAttributeValue('_ReportingAgency','')=='TransUnion') {
                    Transunion.add(node.getAttributeValue('_CreditScore', ''));
                    System.debug('TransUnion: ' + Transunion);                    
                 }
                 }
              }
              
             }
This was selected as the best answer