You need to sign in to do that
Don't have an account?
XML Data into dataTable
Hello,
Just started using apex and VisualForce last week and I'm trying to get some XML data into a dataTable. I'm able to get the XML and parse it using the XmlStreamReader but I keep getting errors when trying to pass it to the dataTable. Here is my code. For now I'm just trying to get text from the usr_conference_id node but eventually I'd like to get the data from the other nodes.
The XML (I'm getting a valid XML doc but removed the header for this post):
<meeting>
<usr_conference_id>382718</usr_conference_id>
<conference_name>Test Conf.</conference_name>
<conference_user>Test User1</conference_user>
</meeting>
<meeting>
<usr_conference_id>381084</usr_conference_id>
<conference_name>Test Conf. 2</conference_name>
<conference_user>Test User2</conference_user>
</meeting>
<apex:page controller="Conferences">
<apex:dataTable value="{!conferencelist}" var="conf">
<apex:column>
<apex:facet name="header">ID</apex:facet>
<apex:outputText value="{!conf.usr_conference_id}"/>
</apex:column>
</apex:dataTable>
</apex:page>
public class Conferences {
public class UserConferences {
String usr_conference_id;
String conference_name;
} // End UserConferences
UserConferences[] parseXML(XmlStreamReader reader) {
UserConferences[] conferences = new UserConferences[0];
while(reader.hasNext()) {
if (reader.getEventType() == XmlTag.START_ELEMENT) {
if ('usr_conference_id' == reader.getLocalName()) {
reader.next();
UserConferences conference = new UserConferences();
conference.usr_conference_id = reader.getText();
conferences.add(conference);
}
}
}
return conferences;
} // End parseXML()
public List<Conferences.UserConferences> getConferenceList() {
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https:ADDRESS REMOVED');
req.setMethod('GET');
HttpResponse res = http.send(req);
// Generate the HTTP response as an XML stream
XmlStreamReader reader = res.getXmlStreamReader();
List<Conferences.UserConferences> conf_return = parseXML(reader);
return conf_return;
}} // End Conferences
When I try to save this in the page editor I get the following error:
System.Exception: Too many script statements: 200001
Class.Conferences.parseXML: line 21, column 13 Class.Conferences.getConferenceList: line 35, column 60 External entry point
Any help would be greatly appreciated!
Thanks,
Dan
Dan,
This post should get you moving again.
Hi Doug,
Thanks for the info. What I'm looking to do is take the data that's in the XML feed and list it in a table with the data being links to other pages. In my code I'm adding the actual text in the tags to an object as it's done in the books example on the XmlStreamReader page. The part I don't understand is how I can pass this object to a dataTable to be displayed (or pageBlockTable, whichever is appropriate). From my understanding of the docs I should be able to pass an object to dataTable and it will automatically iterate over it.
Thanks,
Dan
Ah - sorry - things are always hectic around here during a major release and I read you post too quickly (very little sleep over the weekend). Almost everything in your code looks good except that the way your getConferencesList() method is currently setup you're going to be do way more work than you might expect and I believe that is the reason you are hitting that apex code statement limit (or the data you are attempting to pull through has too many rows?). Try this lazy fetch approach out instead (minor style mods to your page do not effect the result just make you look cooler :-)):
<apex:page controller="Conferences">
<apex:dataTable value="{!conferencelist}" var="conf">
<apex:column headerValue="ID" value="{!conf.usr_conference_id}"/>
</apex:dataTable>
</apex:page>
public class Conferences {
private List<Conferences.UserConferences> conferences;
public class UserConferences {
String usr_conference_id;
String conference_name;
} // End UserConferences
UserConferences[] parseXML(XmlStreamReader reader) {
UserConferences[] conferences = new UserConferences[0];
while(reader.hasNext()) {
if (reader.getEventType() == XmlTag.START_ELEMENT) {
if ('usr_conference_id' == reader.getLocalName()) {
reader.next();
UserConferences conference = new UserConferences();
conference.usr_conference_id = reader.getText();
conferences.add(conference);
}
}
}
return conferences;
} // End parseXML()
public List<Conferences.UserConferences> getConferenceList() {
if (conferences == null) {
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https:ADDRESS REMOVED');
req.setMethod('GET');
HttpResponse res = http.send(req);
// Generate the HTTP response as an XML stream
XmlStreamReader reader = res.getXmlStreamReader();
conferences = parseXML(reader);
}
return conferences;
}} // End Conferences
Hi Doug,
I understand, thanks for helping out on a hectic Monday. The class validates but when I try to save the VF page in the Page Editor I get the following error:
Error: Unknown property 'Conferences.UserConferences.usr_conference_id'
The URL I'm pointing the XmlStreamReader returns the following if I put it in a browser so I know it should be getting some data:
<response>
<result>success</result>
<result_description/>
<conference>
<usr_conference_id>370</usr_conference_id>
<conference_name>Salesforce</conference_name>
<scheduled_time>2009-06-13 17:30:00 -0500</scheduled_time>
<conference_length>60</conference_length>
</conference>
<conference>
<usr_conference_id>368</usr_conference_id>
<conference_name>Test</conference_name>
<scheduled_time>2009-06-03 09:50:00 -0500</scheduled_time>
<conference_length>60</conference_length>
</conference>
</response>
Is it because UserConferences contains another level of objects and we are trying to reference usr_conference_id in UserConferences instead of one level deeper?
Thanks,
Dan
If you haven't tried this : http://developer.force.com/codeshare/apex/ProjectPage?id=a0630000002ahp5AAA
you may want to see if it will help your parsing problem.
you may still hit the limit of statements on long xml source files, so no guarantee that this will solve your issue.
Dan,
The problem/solution is simple - Visualforce requires your classes to expose properties via either getters/setters or native property syntax and UserConferencesjust hasdefault access fields not properties soVF can't see them. Change things to this and you should get past thi:
public class UserConferences {
public String usr_conference_id { get; set; }
public String conference_name { get; set; }
} // End UserConferences
Hi Doug,
That got rid of the error but I'm still getting the "Too many script statements: 200001" error:
System.Exception: Too many script statements: 200001
Class.Conferences.parseXML: line 12, column 13 Class.Conferences.getConferenceList: line 34, column 25 External entry point
My XML file is only 61 lines so I don't see how it can be too long. Here's the XML file I'm pulling in for reference:
http://danday.net/salesforce.xml
Thanks,
Dan
Hi Ron,
Thanks for the link. I've made some progress using the XMLDom parser but hit another roadblock. I'm able to successfully pull out a single text value from a single node with the following code:
public class testXML {
public String conf_ids { get; set; }
public String getConferenceList() {
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('http://danday.net/salesforce.xml');
req.setMethod('GET');
HttpResponse res = http.send(req);
XMLDom responseXML = new XMLDom(res.getBody());
conf_ids = responseXML.getElementsByTagName('conference_name')[0].nodeValue;
return conf_ids;
}
}
Now I'd like to set the conf_ids variable to the entire list of tag names so I can loop through them later like so:
conf_ids = responseXML.getElementsByTagName('conference_name');
What data type do I need to set conf_ids to? If I set it to a List<String> I get the following error:
Error: Compile Error: Illegal assignment from LIST:XMLDom.Element to LIST:String at line 13 column 9
What's the proper data type when returning something from XMLDom?
Thanks,
Dan
XMLDom.Element[] elements = responseXML.getElementsByTagName('conference_name');
for (XMLDom.Element element :elements) {
...
}