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 the
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.
Archived Comments
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...
Maybe to create RSS? Who knows. :)
:(
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.
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.
"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>
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!
@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!
;-)
What, no one is going to suggest deserializeJSON and converting to WDDX?? :D
Ahem: "Outside of WDDX support...."
HAHAHAHAHHA...
I agree, but there's usually one person who brings it up...
Oh...wait...did you edit the post?! I _swear_ I didn't see that earlier...YES I READ IT!!
@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.
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.
@ownsmeister Maybe one of these does not do that...?
http://cflib.org/udf/jsonen...
http://cflib.org/udf/serial...
http://cflib.org/udf/xmlToJson
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.
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.
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.
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!
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.
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.