You need to sign in to do that
Don't have an account?
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!
<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!
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
Use the following code snippet.
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()){
Refer this link as this is very explainable.
https://www.sundoginteractive.com/blog/parsing-xml-in-salesforce-apex
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);
}
}
}
}