You need to sign in to do that
Don't have an account?
doubleminus
XmlStreamReader processing issues. getLocalName() method always returning null. Why??
I'm using Apex to perform some basic XML parsing. I'm having no luck getting to any of the actual XML node names. The getLocalName() method within the XmlStreamReader class always returns null for all nodes as I loop through them.
TEST CLASS:
@isTest private class BPTCalloutTest { private static final String XML_STR = '<document>' + '<result>success</result>' + '<resultcode>000000</resultcode>' + '<note></note>' + '<item>' + '<quantity>1</quantity>' + '<fname>Bob</fname>' + '<lname>Tungsten</lname>' + '<address>23232 Fleet Street</address>' + '<city>Santa Clara</city>' + '<state>CA</state>' + '<zip>94105</zip>' + '<country>United States</country>' + '<email>blahblahblah@blahblahblah.com</email>' + '<phone>4155555555</phone>' + '</item>' + '</document>'; static testMethod void xmlStreamReaderTest() { XmlStreamReader reader = new XmlStreamReader(XML_STR); Opportunity[] opptyList = BPTCallout.parseXML(reader); System.assert(opptyList != null); System.assert(!opptyList.isEmpty()); } }
MAIN CLASS:
public with sharing class BPTCallout { public BPTCallout() {} public static Opportunity[] parseXML(XmlStreamReader reader) { Opportunity[] oppList = new List<Opportunity>(); if (reader != null) { while (reader.hasNext()) { System.debug('$$$ reader.getEventType(): ' + reader.getEventType()); if (reader.getEventType() == XmlTag.END_DOCUMENT) { break; } else if (reader.getEventType() == XmlTag.CHARACTERS) { System.debug('$$$ reader.getLocalName(): ' + reader.getLocalName()); System.debug('$$$ reader.getText(): ' + reader.getText()); System.debug('$$$ reader.getNamespace(): ' + reader.getNamespace()); System.debug('$$$ reader.getlocation(): ' + reader.getlocation()); System.debug('$$$ reader.getprefix(): ' + reader.getprefix()); if (/*reader.getLocalName() == 'lname'*/ reader.getAttributeCount() == 4 && reader.getText() != null) { oppList.add(new Opportunity(Name = reader.getText())); } } reader.next(); } } System.debug('$$$ oppList: ' + oppList); return oppList; } }
Very basic functionality at this point. If you run this, you will see that reader.getLocalName() always returns null and so do all accompanying methods (getNameSpace, getLocation, getPrefix).
Thanks in advance.
I think you are not using the methods in their correct order, which while parsing is very important.
Try this
public static Opportunity[] parseXML(XmlStreamReader reader) {
Opportunity[] oppList = new List<Opportunity>();
if (reader != null){
while (reader.hasNext()){
if(reader.getEventType() == XmlTag.END_DOCUMENT){
break;
}
else if(reader.getEventType() == XmlTag.START_ELEMENT){
if(reader.getLocalName() == 'lname'){
while(reader.hasNext()){
if (reader.getEventType() == XmlTag.END_ELEMENT){
break;
}
else if (reader.getEventType() == XmlTag.CHARACTERS){
System.debug('$$$ reader.getText(): ' + reader.getText());
System.debug('$$$ reader.getNamespace(): ' + reader.getNamespace());
System.debug('$$$ reader.getlocation(): ' + reader.getlocation());
System.debug('$$$ reader.getprefix(): ' + reader.getprefix());
oppList.add(new Opportunity(Name = reader.getText()));
}
reader.next();
}
}
}
reader.next();
}
}
System.debug('$$$ oppList: ' + oppList);
return oppList;
}
All Answers
I think you are not using the methods in their correct order, which while parsing is very important.
Try this
public static Opportunity[] parseXML(XmlStreamReader reader) {
Opportunity[] oppList = new List<Opportunity>();
if (reader != null){
while (reader.hasNext()){
if(reader.getEventType() == XmlTag.END_DOCUMENT){
break;
}
else if(reader.getEventType() == XmlTag.START_ELEMENT){
if(reader.getLocalName() == 'lname'){
while(reader.hasNext()){
if (reader.getEventType() == XmlTag.END_ELEMENT){
break;
}
else if (reader.getEventType() == XmlTag.CHARACTERS){
System.debug('$$$ reader.getText(): ' + reader.getText());
System.debug('$$$ reader.getNamespace(): ' + reader.getNamespace());
System.debug('$$$ reader.getlocation(): ' + reader.getlocation());
System.debug('$$$ reader.getprefix(): ' + reader.getprefix());
oppList.add(new Opportunity(Name = reader.getText()));
}
reader.next();
}
}
}
reader.next();
}
}
System.debug('$$$ oppList: ' + oppList);
return oppList;
}
Hi,
Actually you are not traversing element by element.
First we need to identify that it is a Start Element then, check for the LocalName.If the LocalName matches then, in the next iteration we are checking if the element followed by LocalName is Character, if yes, then we get the text value of that element.
Please see the corrected code below :
Let me know in case of any issues.
Thank you, Vishal and Ramit. Great solutions! I understand this functionality better now.
You are welcome doubleminus!