You need to sign in to do that
Don't have an account?
Displaying XML data in a visualforce page?
I'm new to visualforce/apex so there's probably something fundamental I'm not getting about how VF pages work, but how do I access XML data from within a visualforce page? More specifically, how do I use XML data to generate tables and other elements on a page?
For example, I'm trying to query a remote site for a given person using an id stored in the salesforce database, this remote site returns XML data about this person, including activities this person performed on the remote site -- i.e.:
<xml...>
<Person>
<Id>123</Id>
<Name>John Doe</Name>
<Email>jdoe@example.com</Email>
<Activities>
<Activity>
<Title>Ate a pie</Title>
<Date>2010-01-20 14:26:12 -05:00</Date>
<Url>http://www.example.com/pie</Url>
</Activity>
<Activity>
<Title>Baked a cake</Title>
<Date>2010-01-20 14:26:12 -05:00</Date>
<Url>http://www.example.com/cake</Url>
</Activity>
</Activities>
</Person>
I can load this fine in Apex and parse it with XMLDom, then access the various fields using getElementsByTagName(), getValue(), etc. But how do I display this data on a visualforce page? I've tried saving the 'Person' XMLDom.Element node as a property in a controller class, but can't seem to access any of the sub-elements... i.e.:
public class MyActivities {
public XMLDom.Element person { get; set; }
public MyActivities(...) {
String xml = GetRemoteXML();
String dom = new XMLDom(xml);
person = dom.getElementByName('Person');
}
}
Using:
<b>{!person}</b>
Gets me ... "core.apexpages.el.adapters.ApexObjectValueELAdapter@226dc1" (displayed in the VF page) ... which I assume points to the XMLDom.Element object. (I don't get an error at least...)
But if I try to do any of the following, I get errors:
<b>{!person.name}</b>
<b>{!person.Name}</b>
<b>{!person['name']}</b>
<b>{!person.getValue('name')}</b>
<b>{!person.attributes.name}</b>
<b>{!person.attributes['name']}</b>
I've also tried mapping the XML data to a Map<String,String> property in my controller class:
public Map<String,String> person_map { get; set;}
...
person_map.put('name', dom.getValue('Name'));
But again, in visualforce, I can't figure out how to traverse *into* the map (i.e. {!person_map.Name}, {!person_map['Name']}, {!person_map.get('Name')}, etc.)
Eventually I'd really like to be able to do an <apex: pageBlockTable> around the Activity entries, but if I can't even get to the Name entry, I'm not sure how I would get to something lower down in the XML structure.
I've looked around for examples like this... for examples on using XML data to populate a page and on accessing Maps and other compound elements but didn't find anything helpful.
Everything seems to be based on specific sObjects (Leads, Accounts, Some_Custom_Object__c, etc.) or on scalar controller class properties. Obviously, I don't want to go in and create a whole new '__c' custom object in salesforce just to map and hold this XML data.... I just want to read it from the remote site and display it, I don't need to store it in salesforce.
Have I missed the examples on how to do this?
Thanks,
---Lawrence
I think the right thing to do in this case it to make your own subclass and instatiate it on the controller something like this
Inside your controller write a class:
class person{
public String name{get; set;}
public String last_name{get; set;}
//Then you make the constructor for this class
public person(String name, String last_name){
this.name = name;
this.last_name = last_name;
}
}
once you have your class defined (write it on the bottom of the controller code before the last '}' character
create a variable on the top of the controller as you did with public XMLDom.Element person { get; set; }
and then instantiate it. It would something like this:
public XMLDom.Element personXML { get; set; }
public person myPerson{get; set;}
Then once you got the info loaded on personXML just instantiate myPerson by calling its constructor
myPerson = new myPerson(personXML.getValue('Name), personXML.getValue('last_name'));
now all you need is to acces to myPerson on vf page by simply doing this {!myPerson.name} {!myPerson.last_name}
The fields i put are just an example and i changed the name of your variable person to personXML so i could name my class as person
All Answers
I think the right thing to do in this case it to make your own subclass and instatiate it on the controller something like this
Inside your controller write a class:
class person{
public String name{get; set;}
public String last_name{get; set;}
//Then you make the constructor for this class
public person(String name, String last_name){
this.name = name;
this.last_name = last_name;
}
}
once you have your class defined (write it on the bottom of the controller code before the last '}' character
create a variable on the top of the controller as you did with public XMLDom.Element person { get; set; }
and then instantiate it. It would something like this:
public XMLDom.Element personXML { get; set; }
public person myPerson{get; set;}
Then once you got the info loaded on personXML just instantiate myPerson by calling its constructor
myPerson = new myPerson(personXML.getValue('Name), personXML.getValue('last_name'));
now all you need is to acces to myPerson on vf page by simply doing this {!myPerson.name} {!myPerson.last_name}
The fields i put are just an example and i changed the name of your variable person to personXML so i could name my class as person
Oh, I get it now. I can have lists and sub-objects of other Apex controller-type objects -- all with properties that have getters/setters defined. It's a bit cludgy since that means I have to create new classes for every kind of data I want to display, but I get it.
Thanks! :)
-L
Great. Lawrence-CEC - if you think this has been answered, can you please set hit the "Solution" button on the thread? Thanks!
Jon,
How are you iterating <Activities> on VF page.
I have similar requirement, i followed your thread.
But i am able to display only first record.
How can i iterate <Activities> on vf Page.
Thanks in advance