You need to sign in to do that
Don't have an account?

Generating an XML from VF page using ContentType
Hello Friends,
My requirement is that, i need to generate an XML out of my VF page. For this, i specified the "ContentType="application/xml" on my page header and then included the DOCTYPE tags to generate a standard XML out of it.
But somehow, i am not able to get the XML styling in the generated page and it shows me the shole page elements intead of just showing me the data.
Can you please let me know where i am going wrong or is this possible in VF? Pasting my VF page code below:
<apex:page cache="true" Controller="TestController" contentType="application/xml" showHeader="false">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/html" xml:lang="en" lang="en">
<body>
<apex:form >
<apex:pageblock id="exportDocs">
<apex:pageBlockTable value="{!exportValues}" var="actual">
<apex:column headerValue="Id" value="{!actual.Id}"/>
<apex:column headerValue="Act Name" value="{!actual.Name}"/>
<apex:column headerValue="MType" value="{!actual.A_Type__c}"/>
<apex:column headerValue="Country" value="{!actual.Country__c}"/>
<apex:column headerValue="B" value="{!actual.B__c}"/>
<apex:column headerValue="Actual C" value="{!actual.C__c}"/>
<apex:column headerValue="Actual G" value="{!actual.G__c}"/>
<apex:column headerValue="Actual I" value="{!actual.I__c}"/>
</apex:pageBlockTable>
</apex:pageblock>
</apex:form>
</body>
</html>
</apex:page>
Any help/guidance would be highly appreciated!!
Many Thanks,
Cool_D
if you're getting:
"Save error: The processing instruction target matching "[xX][mM][lL]" is not allowed."
It seems to be a bug in v20 of the API. Try rolling back to 19 or 18 as a solution until it's been patched by Salesforce
All Answers
Can any of the VF architects confirm if what I am trying to do is possible at all or not in VisualForce page??
Thanks
The standard HTML generation centric Visualforce components (e.g. apex:pageBlockTable) do not currently change their rendering based on content type and you need to drop to lower level iteration components etc to perform XML generation (we do this all the time internally BTW). What you are looking for is something like this:
<apex:page controller="TestController" contentType="application/xml"><?xml version="1.0" encoding="UTF-8"?> <myNS:stuff xmlns:myNS="http://www.bogussite.com/namespace/myNamespace"> <apex:repeat value="{!exportValues}" var="actual"> <myNS:myTag name="Id" value="{!actual.Id}"/> <myNS:myTag namw="Act Name" value="{!actual.Name}"/> </apex:repeat> </myNS:stuff> </apex:page> public with sharing class TestController { public TestController() { this.values = new ExportValue[] { new ExportValue('1', 'Name 1'), new ExportValue('2', 'Name 2') }; } public ExportValue[] getExportValues() { return values; } public class ExportValue { public ExportValue(String id, String name) { this.id = id; this.name = name; } public String id { get; private set; } public String name { get; private set; } } private final ExportValue[] values; }
will produce the following XML document:
<?xml version="1.0" encoding="UTF-8"?> <myNS:stuff xmlns:myNS="http://www.bogussite.com/namespace/myNamespace"> <myNS:myTag name="Id" value="1"></myNS:myTag> <myNS:myTag namw="Act Name" value="Name 1"></myNS:myTag> <myNS:myTag name="Id" value="2"></myNS:myTag> <myNS:myTag namw="Act Name" value="Name 2"></myNS:myTag> </myNS:stuff>
Hello Doug,
Well i must say that was something really informative.
Actually, i did not know how to go about it and so i went ahead to write an XML using the XMLStream class.
But surely this one is a short and nice way of doing the same. Will certainly try this one out.
Thanks a ton for your reply!!
Cool_D
Doug,
How can I implement file save dialog instead of Opening XML file in browser window? Can this be done, so that output XML content can be saved to Desktop ...
Hello Doug,
I am trying to follow your example, but when I create the VF page, pasting in your code below, I recieve the following as an error not a warning: "Save error: The processing instruction target matching "[xX][mM][lL]" is not allowed."
Do you or anyone else have a solution to this problem?
For my situation, I need to generate an xml document that lists contacts. To test out the validity of the example, I copied your code word-for-word.
When I follow the threads in this discussion page and this page: http://boards.developerforce.com/t5/Visualforce-Development/How-to-Create-RSS-Feed-using-VF/m-p/204174, I still get the above error.
You help is very much appreciated.
Thanks.
Having the same issue. I need to generate an XML based on an XSD I imported as a static resource.First attempt looks like this, but gives me the error you mentioned:
Controller not doing anything at the moment, just trying to save the VF above.
if you're getting:
"Save error: The processing instruction target matching "[xX][mM][lL]" is not allowed."
It seems to be a bug in v20 of the API. Try rolling back to 19 or 18 as a solution until it's been patched by Salesforce
I was also getting "Save error: The processing instruction target matching "[xX][mM][lL]" is not allowed." error when updated my page to salesforce API v21. In my case I fixed this by:-
I was in impression that first line of visualforce page code should always start with <apex:page>, but seems salesforce have made some changes in new release.
Doug,
This example is very helpful to me as I am trying to render an xslt style sheet from a visual force page. I tried adding the processing instruction right after the <apex:page....> tag as you did....
<apex:page contentType="text/xml" sidebar="false" showHeader="false"><?xml version="1.0" encoding="UTF-8"?>
When I save the page from eclipse, I get an error, rather than a warning....
Save error: The processing instruction target matching "[xX][mM][lL] is not allowed.
Any ideas?
Hi,
Can any one let me know how to generate an Outbound message from Apex
Regards
Munmun
If your myNS example works, why wouldn't this work?
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
</xsl:template>
</xsl:transform>
To create an XSL stylesheet inside VF I need that namespace stuff to work. I must be missing something.
Thanks for sharing this code. This is of great help. But instead of showing warning I see an Error "The processing instruction target matching "[xX][mM][lL]" is not allowed. at line 1" due to which we cannot proceed further. Please let us know if there is any other fix for the same.
thanks,
Saritha
Try setting your API version to 19 in the page's metadata. If that doesn't work, post your code here an I'll compare it to mine.
Hi ,
U can use dom element to parsed the xml
Thanks Tom, I have changed the verison to 19 and it works.
Hello Doug,
I tried to generate the xml in the same way as you suggested. But I am getting a blank screen instead of any xml output.
Please suggest.
Thanks,
Pragati
Post a sample of your xml and VF page, as well as the browser you're using and perhaps we can find the solution.
Hi tggagne,
Visualforce code is:
<apex:page controller="XmlController" contentType="application/xml"><?xml version="1.0" encoding="UTF-8"?>
<myNS:stuff xmlns:myNS="http://www.bogussite.com/namespace/myNamespace">
<apex:repeat value="{!exportValues}" var="actual">
<myNS:myTag name="Id" value="{!actual.Id}"/>
<myNS:myTag namw="Act Name" value="{!actual.Name}"/>
</apex:repeat>
</myNS:stuff>
</apex:page>
I am using the same code for visualforce and apex as mentioned by Daug in the beginning of this board message. However, the code is not working on Google Crome.
Thanks,
Pragati
Pragati, can you describe how the code isnt' working on Chrome?
When I was trying to get mine to work on Chrome (where I tried it first) I had to use a combination of "view page source" and "inspect element."
View Page Source, if I remember, would show me the XML from the page, but not what I was hoping to see. For that I would have to use Inspect Element--then I could see what the XSLT had generated.
Incidentally, I've chucked my original XML page for one that is generated by the controller using XmlStreamWriter. I discovered VisualForce is less-picky about the XML content of the page when its hidden behind a merge field. So now my laboratory XML page looks more like:
The controller examines its page parameters to determine what the client is requesting, and builds the XML using XmlStreamWriter for it. There are advantages and disadvantages to both the Dom and XmlStreamWriter classes. For instance, I don't seem able to insert processing instructions inside Doms but I can write them to the stream.
Sorry about all the posts, but I wrote this code a few weeks ago and haven't needed to revisit it for awhile.
Another approach I took was to use components.
Here is my timesheet page
The component is fairly simple, but demonstrates the use of merge fields to trick VisualForce into doing what we need it to do.
The merge fields are defined inside the controller as
Note: my preference for getters over properties is because the latter cannot be overridden by subclasses.
I just posted this article that relates directly to what you're trying to accomplish--even though yours is already solved.
http://it.toolbox.com/blogs/anything-worth-doing/a-better-way-to-generate-xml-on-salesforce-using-visualforce-55433
<html xmlns="http://www.w3.org/1999/html" xml:lang="en" lang="en">
<response>
<apex:repeat value="{!Accounts}" var="eachAccount" >
<Account id="{!eachAccount.id}" name="{!eachAccount.name}">
<apex:outputPanel rendered="{!!IsBlank(eachAccount.billingStreet)}" layout="none">
<Address type="Billing">
<Street>{!eachAccount.billingStreet}</Street>
<City>{!eachAccount.billingCity}</City>
<State>{!eachAccount.billingState}</State>
<PostalCode>{!eachAccount.billingPostalCode}</PostalCode>
<Country>{!eachAccount.billingCountry}</Country>
</Address>
</apex:outputPanel>
<apex:outputPanel rendered="{!!IsBlank(eachAccount.shippingStreet)}" layout="none">
<Address type="Shipping">
<Street>{!eachAccount.shippingStreet}</Street>
<City>{!eachAccount.shippingCity}</City>
<State>{!eachAccount.shippingState}</State>
<PostalCode>{!eachAccount.shippingPostalCode}</PostalCode>
<Country>{!eachAccount.shippingCountry}</Country>
</Address>
</apex:outputPanel>
<apex:repeat value="{!eachAccount.contacts}" var="eachContact"> <Contact id="{!eachContact.id}" name="{!eachContact.name}" email="{!eachContact.email}"/>
</apex:repeat>
</Account>
</apex:repeat>
</response>
</html>
</apex:page>