Ask a Jedi: How do I convert JSON to XML?

This post is more than 2 years old.

Jody asks:

Quick question... But probably long answer... Is there anyway possible to convert JSON to XML?

Tsk tsk, Jody. I find your lack of faith (in ColdFusion!) to be disturbing! ;) Actually it isn't that difficult at all. The process I'd employ is to first convert the JSON into a native ColdFusion data structure and then convert that to XML. Here are a few examples.

First, let's talk about JSON conversion. In ColdFusion 8, this is a no-brainer. It's just built in. So to convert some data into JSON I could do this:

<cfset s = {}> <cfset s.name = "Raymond Camden"> <cfset s.age = 36> <cfset s.kids = ["Jacob","Lynn","Noah"]> <cfset s.handed = "left">

<cfset jsonVersion = serializeJSON(s)> <cfoutput>json version=#jsonVersion#<p></cfoutput>

This returns: json version={"HANDED":"left","NAME":"Raymond Camden","AGE":36.0,"KIDS":["Jacob","Lynn","Noah"]}

Now if we pretend we began with that JSON, converting it back into ColdFusion is as simple as:

<cfset data = deserializeJSON(jsonVersion)>

Note - if you don't have ColdFusion 8, I recommend the CFJSON CFC for JSON conversion. It's like butter.

Ok, so at this point we are back to having native ColdFusion data, how do we convert it to XML? Outside of WDDX support, there is no way to convert dynamic ColdFusion data into XML. I've got my own little CFC for that, toXML, but I never updated it to be recursive. I picked a random project from RIAForge, AnythingToXML, and decided to use that. It works ok, but note that it assumes you want to serve up the XML data instead of actually work with it. I manually edited the project's CFC to remove thetag.

Anyway, after a few seconds looking at the docs, I was able to generate the XML like so:

<!--- then convert to xml ---> <cfset xmlcfc = createObject("component", "AnythingToXML.AnyThingToXml")> <cfset packet = xmlcfc.toXML(data,"data")>

<cfoutput>#htmlEditFormat(packet)#</cfoutput>

Not really rocket science, but it works. Of course, you don't have to use a component. If you know the form of your data, you can always build the XML manually. Consider the following template. It makes use of the Twitter API to get JSON data for a search. I then loop over the results and generate XML.

<cfset q = "coldfusion"> <cfhttp url="http://search.twitter.com/search.json?q=#urlEncodedFormat(q)#" result="result">

<cfset data = deserializeJSON(result.fileContent)>

<cfxml variable="packet"> <twitterresults> <cfoutput> <query>#xmlFormat(q)#</query> <cfloop index="r" array="#data.results#"> <result> <user>#xmlFormat(r.from_user)#</user> <created>#xmlFormat(r.created_at)#</created> <text>#xmlFormat(r.text)#</text> </result> </cfloop> </cfoutput> </twitterresults> </cfxml>

<cfdump var="#packet#">

The Twitter API returns more information than what I've used. I kept things simple though. Here is a quick screen shot showing the result:

One quick last note - well ok, two quick notes. First off - the Twitter API kicks major butt. I'm blown away with how simple it is to use and how - lord forbid - how much it helps you actually use it. (Google - are you listening? Please don't buy Twitter and ruin the API.) Secondly - Twitter supports ATOM results. This is a flavor of RSS and is XML already, so technically, I wouldn't need to convert the JSON.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by todd sharp posted on 9/2/2009 at 5:35 PM

I guess I'm wondering why Jody wants to convert JSON to XML? What language/framework can't grok JSON? There's even a lib for JSON encode/decode for Flex/AS3...

Comment 2 by Raymond Camden posted on 9/2/2009 at 5:43 PM

Maybe to create RSS? Who knows. :)

Comment 3 by Jody Fitzpatrick posted on 9/2/2009 at 5:45 PM

:(

Ha, Ha. I have faith in ColdFusion. I completely abandoned php for it. I'm just now starting to get use to external data other than the basic databases.

But thank you so much Ray for writting this it really helped me.

Comment 4 by Jody Fitzpatrick posted on 9/2/2009 at 6:12 PM

Well I'm actually working on a search engine. It is a project for myself to teach me all about ColdFusion. Once I finish it not only will I have taught myself a lot but I will have something I can use and hopefully others can use as well.

Comment 5 by John Bliss posted on 9/2/2009 at 6:27 PM

"Consider the following template. It makes use of the Twitter API..."

Or, if you prefer, you could use CF's XML-building functions:

<cfset packet = xmlnew()>
<cfset packet.twitterresults = xmlelemnew(packet, "twitterresults")>
<cfset packet.twitterresults.query = xmlelemnew(packet, "query")>
<cfset packet.twitterresults.query.xmltext = xmlFormat(q)>
<cfset i = 0>
<cfloop index="r" array="#data.results#">
<cfset i = i + 1>
<cfset ArrayAppend(packet.twitterresults.query.xmlchildren, xmlelemnew(packet, "result"))>
<cfset packet.twitterresults.query.result[i].user = xmlelemnew(packet, "user")>
<cfset packet.twitterresults.query.result[i].user.xmltext = xmlFormat(r.from_user)>
<cfset packet.twitterresults.query.result[i].created = xmlelemnew(packet, "created")>
<cfset packet.twitterresults.query.result[i].created.xmltext = xmlFormat(r.created_at)>
<cfset packet.twitterresults.query.result[i].text = xmlelemnew(packet, "text")>
<cfset packet.twitterresults.query.result[i].text.xmltext = xmlFormat(r.text)>
</cfloop>

Comment 6 by Raymond Camden posted on 9/2/2009 at 6:29 PM

I'm sorry John. You are wrong. There is only one way to do it.

;)

John brings up a good point Jody - never forget there are _multiple_ ways to skin the cat in ColdFusion!

Comment 7 by John Bliss posted on 9/2/2009 at 6:33 PM

@Ray [whew] Read, "I'm sorry John. You are wrong. There is only one way to do it," before seeing the ;-) and, because it was coming from the Jedi Master, nearly gave up on my career to go work at Starbucks!

;-)

Comment 8 by todd sharp posted on 9/2/2009 at 6:48 PM

What, no one is going to suggest deserializeJSON and converting to WDDX?? :D

Comment 9 by Raymond Camden posted on 9/2/2009 at 6:59 PM

Ahem: "Outside of WDDX support...."

Comment 10 by todd sharp posted on 9/2/2009 at 7:20 PM

HAHAHAHAHHA...

I agree, but there's usually one person who brings it up...

Comment 11 by todd sharp posted on 9/2/2009 at 7:21 PM

Oh...wait...did you edit the post?! I _swear_ I didn't see that earlier...YES I READ IT!!

Comment 12 by Chris posted on 9/2/2009 at 9:01 PM

@Jody: That's a first for me. Someone abandoning PHP for CF? Normally it's the other way around (due more in part to lack of CF jobs in comparison to PHP).

But, I'm at a company that uses PHP predominantly and I'm getting the hang of it...sorta. I can see why I don't want to lose my CF focus. PHP is really cryptic, comparitively that is.

Comment 13 by ownsmeister posted on 9/4/2009 at 9:50 AM

one thing, that's really bothering me is, that Coldfusion capitalizes all properties when you use serializeJSON.
I've had many hours of banging my head against the table because of this.

Comment 14 by John Bliss posted on 9/4/2009 at 3:12 PM
Comment 15 by Raymond Camden posted on 9/4/2009 at 3:54 PM

Thats not a serializeJSON issue, but how CF stores structs. When you do x.y = "foo", you will always end up with a capital Y as the key. However, if you change your code to do:

x["y"]

then the case will be maintained.

Comment 16 by phpEmperor posted on 2/2/2010 at 8:45 PM

Interesting post. I enjoy Coldfusion and PHP equally. The problem I run with Coldfusion is lack of documentation or hidden function that are often buried. Those individuals who grew sipping on Coldfusion milk find php a bit difficult but I've grown off c/c++ before going to php/web development and thought that PHP was such an easy language. Now that I'm a Coldfusion developer I've come realize that there are some aspects of development that Coldfusion developers take for granted and laugh while shaking my head when comments regarding the difficulty of PHP is made.

Comment 17 by Raymond Camden posted on 2/2/2010 at 8:48 PM

Can I ask - why do you say lack of documentation? There is something like 3000 pages of docs (reference + developer guide) available both online and for download.

Comment 18 by Daniel Gaspar posted on 10/16/2010 at 12:16 AM

Glad you got AnythingToXML working for you. Hey that's the beauty of opensource: if it doesn't work you can modify the code to make it do exactly what you need!

Comment 19 by John M posted on 8/30/2012 at 12:16 AM

This post still very useful in 2012.

Is this still the only way to convert native CF objects (Structures/array etc) into XML?

I've been looking for a way to do this, and this is the only solution I have found.
I know that CF10 can do it under the hood, to covert cffunction output types into XML responses from a RESTful service, but can't find a simple way to expose that, so reverting to AnythingToXML.

Comment 20 by Raymond Camden posted on 8/30/2012 at 12:48 AM

There is the cfwddx tag - but - WDDX is a bit verbose (although all XML is a bit verbose). I've always built my XML by hand so I can have precise control.