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
Lawrence-CECLawrence-CEC 

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

 

 

 

Best Answer chosen by Admin (Salesforce Developers) 
imuinoimuino

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

Message Edited by imuino on 03-15-2010 02:04 PM

All Answers

imuinoimuino

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

Message Edited by imuino on 03-15-2010 02:04 PM
This was selected as the best answer
Lawrence-CECLawrence-CEC

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

Jon Mountjoy_Jon Mountjoy_

Great.  Lawrence-CEC - if you think this has been answered, can you please set hit the "Solution" button on the thread?  Thanks! 

Nidhi SharmaNidhi Sharma

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