• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 721
  • Last Modified:

Cold Fusion parsing a JSON feed from a URL

I want to be able to parse this feed so I can extract the photo URL's and iterate a CFLOOP of the URL's to populate a photo album on my website.

I see the data in the feed, but don't know how to parse it to get the photo URL's I want.  I read about the deserializeJSON() tag, but have no idea how to just pull the photo URL's.

HELP!

https://graph.facebook.com/265379466888505/photos
0
day6
Asked:
day6
  • 4
  • 3
1 Solution
 
day6Author Commented:
Just need the way to DUMP the data into a CFLOOP, but only the URL's for the photos.
0
 
Pravin AsarPrincipal Systems EngineerCommented:
Here is a start for you.


<!--- Get the JSON Feed --->
<cfhttp url="https://graph.facebook.com/265379466888505/photos">
 
<!--- JSON data is sometimes distributed as a JavaScript function.
     The following REReplace functions strip the function wrapper. --->
<cfset theData=REReplace(cfhttp.FileContent,  "^\s*[[:word:]]*\s*\(\s*","")>
<cfset theData=REReplace(theData, "\s*\)\s*$", "")>
<!---<cfdump var="#theData#"> --->
 
<!--- Test to make sure you have JSON data. --->
<cfif !IsJSON(theData)>
    <h3>The URL you requested does not provide valid JSON</h3>
<!--- If the data is in JSON format, deserialize it. --->
<cfelse>
    <cfset cfData=DeserializeJSON(theData)>
    <!---<cfdump var="#cfdata#">--->
    <!--- Parse the resulting array or structure and display the data.
             In this case, the data represents a ColdFusion query that has been
             serialized by the SerializeJSON function into a JSON structure with
             two arrays: an array column names, and an array of arrays,  
             where the outer array rows correspond to the query rows, and the
             inner array entries correspond to the column fields in the row. --->
    <!--- First, find the positions of the columns in the data array. --->
      <cfdump var="#(cfdata)#"/>
</cfif>
0
 
day6Author Commented:
pravinasar:

That is the Adobe example for how to use their tag, but doesn't demonstrate how to parse or extract the columns and rows from this URL feed I provided.  I've already read through their documentation and found it to be useless for my sake since I have no idea how to iterate through the cfdump to extract the URL's from the JSON feed.

I need help knowing how to parse the JSON into the pieces of data I can use to then CFLOOP a script to generate a photo album dynamically.  I've parsed XML feeds before using the CF tag, but this one doesn't have adequate documentation to help me understand how to use it.
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
sumColdCommented:
The output of JSON structure is mixture of structure and Array.. this so because adobe example fails to extract it. Try below code:



<!--- Get the JSON Feed --->
<cfhttp url="https://graph.facebook.com/265379466888505/photos">

<!--- JSON data is sometimes distributed as a JavaScript function.
     The following REReplace functions strip the function wrapper. --->
<cfset theData=REReplace(cfhttp.FileContent,
        "^\s*[[:word:]]*\s*\(\s*","")>
<cfset theData=REReplace(theData, "\s*\)\s*$", "")>

<!--- Test to make sure you have JSON data. --->
<cfif !IsJSON(theData)>
    <h3>The URL you requested does not provide valid JSON</h3>
    <cfdump var="#theData#">

<!--- If the data is in JSON format, deserialize it. --->
<cfelse>
    <cfset cfData=DeserializeJSON(theData)>
    <!--- Parse the resulting array or structure and display the data.
             In this case, the data represents a ColdFusion query that has been
             serialized by the SerializeJSON function into a JSON structure with
             two arrays: an array column names, and an array of arrays,
             where the outer array rows correspond to the query rows, and the
             inner array entries correspond to the column fields in the row. --->
    <!--- First, find the positions of the columns in the data array. --->
   
            <cfoutput>
            <cfloop collection="#cfData#" item="key">
                  <cfloop array="#cfData['data']#" index="struct2">
                        <cfloop collection="#struct2#" item="key2">
                              <cfloop array="#struct2['images']#" index="struct3">
                                    <img src="#struct3['source']#" height="#struct3['height']#" width="#struct3['width']#">
                              </cfloop>
                        </cfloop>
                  </cfloop>
            </cfloop>
            </cfoutput>
</cfif>
0
 
Pravin AsarPrincipal Systems EngineerCommented:
I am sure how to navigate through structures and array of structures.

Anyway, here are some pointers.

<!--- Get the JSON Feed --->
<cfhttp url="https://graph.facebook.com/265379466888505/photos">
 
<!--- JSON data is sometimes distributed as a JavaScript function.
     The following REReplace functions strip the function wrapper. --->
<cfset theData=REReplace(cfhttp.FileContent,  
        "^\s*[[:word:]]*\s*\(\s*","")>
<cfset theData=REReplace(theData, "\s*\)\s*$", "")>
    <!---<cfdump var="#theData#"> --->
 
<!--- Test to make sure you have JSON data. --->
<cfif !IsJSON(theData)>
    <h3>The URL you requested does not provide valid JSON</h3>
 
<!--- If the data is in JSON format, deserialize it. --->
<cfelse>
    <cfset cfData=DeserializeJSON(theData)>
    <!---<cfdump var="#cfdata#">--->
   
 
    <!--- Now iterate through the DATA array and display the data. --->
    <cfoutput>STRUCT KEY LIST: #StructKeyList(cfdata)#</cfoutput>      
    <cfloop collection="#cfdata#" item="item">
                <cfoutput><br/><h1>Element is #item#</h1></cfoutput>
                <cfset vardata=#evaluate("cfdata." & #item#)#/>
                <cfif #item# is "data">
                <cfif #IsArray(vardata)#>
                      <cfoutput><br/>Array Length : #arraylen(vardata)#</cfoutput>
                      <cfloop index="ix" from="1" to="#arraylen(vardata)#">
                            <cfoutput><h1>ARRAY ELEMENT #ix#</h1></cfoutput>
                            <cfdump var="#vardata[ix]#">
                            <cfif #IsStruct (vardata[ix])#>
                                  <cfoutput><h2>STRUCT KEYS:  #StructKeyList(vardata[ix])#</h2></cfoutput>
                            </cfif>
                      </cfloop>
                </cfif>
                </cfif>
    </cfloop>
</cfif>
0
 
Pravin AsarPrincipal Systems EngineerCommented:
I am very well aware of structure and arrays, having done  tons of c/c++ and java development.

I agree, Adobe example is misleading.
0
 
day6Author Commented:
Ok... I'm almost there. Your code helped me understand how to sort through which KEYS are required. I also didn't understand how to display the data in an array "visually" and your code did that. I now am able to at least visually see how to try and write a code to provide me the IMG source URL.

However, I have written this below snippet of code to try and isolate only 1 URL from a subset of data instead of having all 8 URLs provided.  My code works using the CFIF statement, but I'm getting 8 repeated results in the output where i only need 1 result.  Do arrays work like query outputs in that I can use a <CFIF CurrentRow is 4> or because it's in a CFLOOP, I can't do that? Based on the array output, I know that the 4th row is the URL I want, so I tried to use the HEIGHT attribute to filter my result set, but still get 8 repeated URLs.

<cfoutput>
            <cfloop collection="#cfData#" item="key">
                  <cfloop array="#cfData['data']#" index="struct2">
                        <cfloop collection="#struct2#" item="key2">
                              <cfloop array="#struct2['images']#" index="struct3">
                                    <cfif struct3['height'] is 480>
                                                      #struct3['source']#<hr />
                                                      </cfif>
                              </cfloop>
                        </cfloop>
                  </cfloop>
            </cfloop>
            </cfoutput>
0
 
Pravin AsarPrincipal Systems EngineerCommented:
Your are looping over all keys, hence it is printing many matches.

Anyway, here is a simplified code


      <cfoutput>
            <cfset cnt1 = 1>
            <cfloop array="#cfData['data']#" index="struct2">
                  <cfset cnt2 = 1>
                  <cfloop array="#struct2['images']#" index="struct3">
                        <cfif struct3['height'] is 480>
                              <cfdump var="#struct3#">
                              <br/>
                              #cnt1#
                              :
                              #cnt2#
                              :
                              #struct3['source']#
                        </cfif>
                        <cfset cnt2 = cnt2 + 1>
                  </cfloop>
                  <cfset cnt1 = cnt1 + 1>
            </cfloop>
      </cfoutput>
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now