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
DDayDDay 

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 

 

Message Edited by DDay on 06-07-2009 07:22 PM
dchasmandchasman

Dan,

 

This post should get you moving again.

DDayDDay

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 

dchasmandchasman

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

DDayDDay

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

 

Ron HessRon Hess

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.

dchasmandchasman

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

 

DDayDDay

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 

DDayDDay

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

Ron WildRon Wild

XMLDom.Element[] elements = responseXML.getElementsByTagName('conference_name');

 

for (XMLDom.Element element :elements) {

       ...

}