+ Start a Discussion
Cool_DevloperCool_Devloper 

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
Best Answer chosen by Admin (Salesforce Developers) 
Joseph FerraroJoseph Ferraro

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

Cool_DevloperCool_Devloper

Can any of the VF architects confirm if what I am trying to do is possible at all or not in VisualForce page??

 

Thanks 

dchasmandchasman

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>

 

 

NOTE: the placement of the XML declaration must be like I have it in the example (on the same line as the apex:page tag) and you will get a VF compiler warning "Warning: The processing instruction target matching "[xX][mM][lL]" is not allowed. at line 1" that you can ignore for now (we have a bug open tracking this long standing issue).

 

Cool_DevloperCool_Devloper

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

VarunCVarunC

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 ...

PSteves91PSteves91

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.

HarmpieHarmpie

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:

 

<apex:page controller="AttestToXmlController" contentType="application/xml"><?xml version="1.0" encoding="UTF-8"?>
<Verzendingen xsi:noNamespaceSchemaLocation="{!$Resource.Belcotaxxsd}">

</Verzendingen>
</apex:page>

 

Controller not doing anything at the moment, just trying to save the VF above.

 

Joseph FerraroJoseph Ferraro

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

This was selected as the best answer
Rajendra ORajendra O

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:-

 

ERROR:- 
<apex:page controller="Controller" contentType="text/xml"><?xml version="1.0" encoding="UTF-8"?></apex:page>

FIX:-
<?xml version="1.0" encoding="UTF-8"?><apex:page controller="Contorller" contentType="application/xml"></apex:page>

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.

Tom H.Tom H.

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?

MunmunMunmun

Hi,

Can  any one let me know   how to generate  an Outbound message from Apex

 

 

Regards

 

Munmun

tggagnetggagne

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.

Saritha MSaritha M

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

Tom G.ax970Tom G.ax970

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.

MunmunMunmun

Hi ,

U can use dom element to parsed the xml

Saritha MSaritha M

Thanks Tom, I have changed the verison to 19 and it works.

 

Force.comForce.com

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

tggagnetggagne

Post a sample of your xml and VF page, as well as the browser you're using and perhaps we can find the solution.

Force.comForce.com

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

tggagnetggagne

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.

tggagnetggagne

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:

 

<apex:page controller="AquariusXMLController" contentType="application/xml" showHeader="false" sidebar="false" expires="1">
	<apex:outputText value="{!respond}" />
</apex:page>

 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.

tggagnetggagne

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 

<apex:page controller="TimeSheetWeekController" contentType="application/xml" showHeader="false" sidebar="false" expires="1">
<c:XmlWrapper >
	<response>
		<timesheet startDate="{!startDateString}" employeeNumber="{!personInfo.staffIdList}"
			nodeNext="timesheetXml?startDate={!nodeNext}"
			nodePrevious="timesheetXml?startDate={!nodePrevious}">
			<apex:repeat value="{!rowlist}" var="row">
				<jobweek 
					employeeNumber="{!row.jobWeek.employeeNumber}"
					userName="{!row.jobWeek.userName}"
					description="{!row.jobWeek.description}" 
					jobNumber="{!row.jobWeek.jobNumber}" 
					jobStep="{!row.jobWeek.jobStep}" 
					jobtype="{!row.jobWeek.jobType}" 
					payType="{!row.jobWeek.payType}"
					isMachineTime="{!row.jobWeek.isMachineTime}">
					<jobDay day="sun" value="{!row.jobWeek.sundayHours}" />
					<jobDay day="mon" value="{!row.jobWeek.mondayHours}" />
					<jobDay day="tue" value="{!row.jobWeek.tuesdayHours}" />
					<jobDay day="wed" value="{!row.jobWeek.wednesdayHours}" />
					<jobDay day="thu" value="{!row.jobWeek.thursdayHours}" />
					<jobDay day="fri" value="{!row.jobWeek.fridayHours}" />
					<jobDay day="sat" value="{!row.jobWeek.saturdayHours}" />
				</jobweek>
			</apex:repeat>		
		</timesheet>
	</response>
</c:XmlWrapper>
</apex:page>

The component is fairly simple, but demonstrates the use of merge fields to trick VisualForce into doing what we need it to do.

<apex:component controller="AquariusXMLController">{!xmlpi}
{!stylesheetReference}
<apex:componentBody />
</apex:component>

The merge fields are defined inside the controller as

public string getStylesheetReference() { return '<?xml-stylesheet type="text/xsl" href="AquariusXSLT" ?>'; }

public string getXMLPI() { return '<?xml version="1.0"?>'; }
	

 Note: my preference for getters over properties is because the latter cannot be overridden by subclasses.

 

 

Force.comForce.com
Hi tggagne,
Thanks a lot for your help. I tried your code and it worked.
But still I am not able to understand that why chrome is showing a blank screen and not the xml output. I also don't know how to use Inspect element for that.
Thanks,
Pragati
Tom G.ax970Tom G.ax970

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

dj.swain131.3932574279461172E12dj.swain131.3932574279461172E12
<apex:page StandardController="Account" recordSetVar="Accounts" contentType="text/xml" showHeader="false" sidebar="false" cache="false">


<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>
dj.swain131.3932574279461172E12dj.swain131.3932574279461172E12

<html lang="en" xml:lang="en"><response>
<Account id="0019000000wMc8xAAC" name="british">
    </Account><Account id="0019000000Sxuk3AAB" name="Burlington Textiles Corp of America"><Address type="Billing"><Street>525 S. Lexington Ave</Street><City>Burlington</City><State>NC</State><PostalCode>27215</PostalCode><Country>USA</Country></Address><Contact email="jrogers@burlington.com" id="0039000000SiTqNAAV" name="Jack Rogers"/></Account>
output like this xml code