Thursday, October 6, 2016

Format JSON String in ColdFusion

I am sure this has probably already been done but I couldn't find it quickly with a Google search. So I wrote my own. This function takes a JSON string and indents it to make it more readable.
<cffunction name="indentJSON" hint="Indents JSON to make it more readable">
    <cfargument name="JSONString" default="" hint="JSON string to be formatted">
    <cfargument name="indentCharacters" default="#Chr(9)#" hint="Character(s) to use for indention">

    <cfset local.inQuotes = false>
    <cfset local.indent = 0>
    <cfset local.returnString = "">
    <cfset local.stringLength = Len(arguments.JSONString)>
    <cfloop index="i" from="1" to="#local.stringLength#">
        <cfset local.currChar = Mid(arguments.JSONString, i, 1)>
        <cfif i lt local.stringLength - 1>
            <cfset local.nextChar = Mid(arguments.JSONString, i + 1, 1)>
        <cfelse>
            <cfset local.nextChar = "">
        </cfif>
        <cfif local.currChar eq '"'>
            <cfset local.inQuotes = !local.inQuotes>
        </cfif>
        <cfif local.inQuotes>
            <cfset local.returnString = local.returnString & local.currChar>
        <cfelse>
            <cfswitch expression="#local.currChar#">
                <cfcase value="{">
                    <cfset local.indent = local.indent + 1>
                    <cfset local.returnString = local.returnString & "{" & Chr(10) & RepeatString(arguments.indentCharacters, local.indent)>
                </cfcase>
                <cfcase value="}">
                    <cfset local.indent = local.indent - 1>
                    <cfset local.returnString = local.returnString & Chr(10) & RepeatString(arguments.indentCharacters, local.indent) & "}">
                    <cfif local.nextChar neq ",">
                        <cfset local.returnString = local.returnString & Chr(10)>
                    </cfif>
                </cfcase>
                <cfcase value="," delimiters="Chr(0)">
                    <cfset local.returnString = local.returnString & "," & Chr(10) & RepeatString(arguments.indentCharacters, local.indent)>
                </cfcase>
                <cfcase value=":">
                    <cfif local.nextChar neq " ">
                        <cfset local.returnString = local.returnString & ": ">
                    </cfif>
                </cfcase>
                <cfdefaultcase>
                    <cfset local.returnString = local.returnString & local.currChar>
                </cfdefaultcase>
            </cfswitch>
        </cfif>
    </cfloop>

    <cfreturn trim(local.returnString)>
</cffunction>
And here's an example:
<cfset variables.testObject = {}>
<cfset variables.testObject.name.first = "Chad">
<cfset variables.testObject.name.last = "Armond">
<cfset variables.testObject.title = "Software Developer">

<cfset variables.testString = SerializeJSON(variables.testObject)>

<cfoutput>
    <h1>With Tabs (Default)</h1>
    <cfset variables.json1 = indentJSON(variables.testString)>
    <pre>#variables.json1#</pre>

    <h1>With Spaces</h1>
    <cfset variables.json2 = indentJSON(variables.testString, "    ")>
    <pre>#variables.json2#</pre>
</cfoutput>
And the results:

With Tabs (Default)

{
 "NAME": {
  "LAST": "Armond",
  "FIRST": "Chad"
 },
 "TITLE": "Software Developer"
}

With Spaces

{
    "NAME": {
        "LAST": "Armond",
        "FIRST": "Chad"
    },
    "TITLE": "Software Developer"
}

0 comments:

Post a Comment

 
Blogger Templates