Page 1 of 1

Json array question

Posted: Sat Oct 24, 2020 11:06 am
by Evil1
Hi all,

I am new to JSON and am having difficulty figuring out how to grab the information from an array[object]

e.g. genres

Image

Code: Select all

{"adult":false,"backdrop_path":null,"belongs_to_collection":null,"budget":0,"genres":[{"id":18,"name":"Drama"}],"homepage":null,"id":600635,"imdb_id":"tt0009029","original_language":"en","original_title":"The Eagle's Eye","overview":"Silent film serial","popularity":0.676,"poster_path":"/5XGJX5ErUemM0zBoHj8BOrfV5AP.jpg","production_companies":[{"id":58028,"logo_path":null,"name":"Wharton","origin_country":""}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"release_date":"1918-03-27","revenue":0,"runtime":null,"spoken_languages":[],"status":"Released","tagline":"","title":"The Eagle's Eye","video":false,"vote_average":0.0,"vote_count":0}
I can grab the title, imdb_id etc. with the following code. But struggling with the array side. I have gone through dozens of JSON topics on this board but still not much wiser

Code: Select all

InitNetwork()

Structure JSONStructure
  adult.i
  backdrop_path.s
  ;belongs_to_collection.s
  budget.i
  ;List genres.s()
  homepage.s
  id.i
  imdb_id.s
  original_language.s
  original_title.s
  overview.s
  ;popularity.i
  poster_path.s
  ;List production_companies.s()
  ;List production_countries.s()
  ;release_date.s
  revenue.i
  ;Runfor.i
  ;spoken_languages.s
  status.s
  tagline.s
  title.s
  ;video.i
  ;vote_average.i
  ;vote_count.i
 EndStructure

Structure genres
  id.i
  name.s
 EndStructure
    
Define ReturnValue.s
Define Buffer, Size
Define Movie.i = 600635
Define ApiKey.s = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Buffer = ReceiveHTTPMemory("http://api.themoviedb.org/3/movie/"+Str(Movie)+"?api_key=" + ApiKey + "&language=en-US")


If Buffer
  Size = MemorySize(Buffer)
  ReturnValue = PeekS(Buffer, Size, #PB_UTF8)
EndIf

Debug ReturnValue


JSON = ParseJSON(#PB_Any, ReturnValue)

Define JM.JSONStructure
Define JM2.genres

If JSON
  ExtractJSONStructure(JSONValue(JSON), @JM, JSONStructure)
  ;ExtractJSONList(JSONValue(JSON),genre())
  Debug JM\title
  Debug JM\imdb_id
  FreeJSON(JSON)
EndIf
I would appreciate it if someone could give me some pointers.

thanks

Re: Json array question

Posted: Sat Oct 24, 2020 12:52 pm
by infratec
This should work:

Code: Select all

EnableExplicit

Structure GenresStructure
  id.i
  name.s
EndStructure


Structure ProductionCompaniesStructure 
  id.i
  logo_path.s
  name.s
  origin_country.s
EndStructure


Structure ProductionCountriesStructure
  iso_3166_1.s
  name.s
EndStructure

Structure SpokenLanguagesStructure
  iso_639_1.s
  name.s
EndStructure


Structure JSONStructure
  adult.i
  backdrop_path.s
  belongs_to_collection.s
  budget.i
  List genres.GenresStructure()
  homepage.s
  id.i
  imdb_id.s
  original_language.s
  original_title.s
  overview.s
  popularity.f
  poster_path.s
  List production_companies.ProductionCompaniesStructure()
  List production_countries.ProductionCountriesStructure()
  release_date.s
  revenue.i
  Runtime.s
  List spoken_languages.SpokenLanguagesStructure()
  status.s
  tagline.s
  title.s
  video.i
  vote_average.f
  vote_count.i
EndStructure



Define JSON.i
Define ReturnValue.s
Define JM.JSONStructure


ReturnValue = ~"{\"adult\":false,\"backdrop_path\":null,\"belongs_to_collection\":null,\"budget\":0,\"genres\":[{\"id\":18,\"name\":\"Drama\"}],\"homepage\":null,\"id\":600635,\"imdb_id\":\"tt0009029\",\"original_language\":\"en\",\"original_title\":\"The Eagle's Eye\",\"overview\":\"Silent film serial\",\"popularity\":0.676,\"poster_path\":\"/5XGJX5ErUemM0zBoHj8BOrfV5AP.jpg\",\"production_companies\":[{\"id\":58028,\"logo_path\":null,\"name\":\"Wharton\",\"origin_country\":\"\"}],\"production_countries\":[{\"iso_3166_1\":\"US\",\"name\":\"United States of America\"}],\"release_date\":\"1918-03-27\",\"revenue\":0,\"Runtime\":null,\"spoken_languages\":[],\"status\":\"Released\",\"tagline\":\"\",\"title\":\"The Eagle's Eye\",\"video\":false,\"vote_average\":0.12,\"vote_count\":1}"
;Debug ReturnValue
;Debug ""

JSON = ParseJSON(#PB_Any, ReturnValue)
If JSON
  
  Debug ComposeJSON(JSON, #PB_JSON_PrettyPrint)
  Debug ""
  
  ExtractJSONStructure(JSONValue(JSON), @JM, JSONStructure)
  Debug JM\title
  Debug JM\original_language + " -> " + JM\original_title
  Debug JM\imdb_id
  Debug JM\status
  Debug JM\release_date
  
  ForEach JM\genres()
    Debug JM\genres()\name
  Next
  
  ForEach JM\production_companies()
    Debug JM\production_companies()\name + " " + JM\production_companies()\origin_country
  Next
  
  ForEach JM\production_countries()
    Debug JM\production_countries()\iso_3166_1 + " " + JM\production_countries()\name
  Next
  
  Debug Str(JM\vote_count) + " -> " + StrF(JM\vote_average)
  
  Debug JM\popularity
  
  FreeJSON(JSON)
EndIf

Re: Json array question

Posted: Sat Oct 24, 2020 3:17 pm
by Evil1
Thanks Infra, it's easy when you know how :-)

Re: Json array question

Posted: Sat Oct 24, 2020 8:07 pm
by Evil1
I made some great progress, thanks to Infra. But now my application is crashing with a #JSON not intialised whilst parsing through some of the results :-

For example the folowing JSON returned results :-

Code: Select all

{"page":1,"total_results":1,"total_pages":1,"results":[{"popularity":33.984,"id":13207,"video":false,"vote_count":1589,"vote_average":5.8,"title":"Friday the 13th","release_date":"2009-02-11","original_language":"en","original_title":"Friday the 13th","genre_ids":[27],"backdrop_path":"\/1wifwQ25N27DCIBRqvG3lKkZua3.jpg","adult":false,"overview":"Ignoring the warnings of the locals, a group of teenage camp counselors takes on the job of reopening Camp Crystal Lake — on Friday the 13th no less, and raise the ire of Jason Voorhees, a masked, homicidal maniac.","poster_path":"\/fLTQgFpOJA4iyuazewxPof13xSY.jpg"}]}12

Code: Select all

{"page":1,"total_results":1,"total_pages":1,"results":[{"popularity":23.271,"vote_count":316,"video":false,"poster_path":"\/2KLel13fLyOqN6NCP9N2JO8rbGn.jpg","id":27850,"adult":false,"backdrop_path":"\/4sPNSukUSP1Jc69Q2mkWuxf7QQp.jpg","original_language":"en","original_title":"Halloweentown","genre_ids":[12,35,14,27,10751,10770],"title":"Halloweentown","vote_average":6.9,"overview":"On her 13th birthday, Marnie learns she's a witch, discovers a secret portal, and is transported to Halloweentown — a magical place where ghosts and ghouls, witches and werewolves live apart from the human world. But she soon finds herself battling wicked warlocks, evil curses, and endless surprises.","release_date":"1998-11-10"}]}re
I managed to skip over these by using the following bit of code :-

Code: Select all

 If ParseJSON(0, ReturnValue)
              ExtractJSONStructure(JSONValue(0), @Movies.sSearchResult, sSearchResult)
            Else
              Debug "Error "+JSONErrorMessage()+"|"+B$ +" From "+ReturnValue
              f=1
            EndIf
                      
            If f=0:FreeJSON(0):EndIf 
JSONErrorMessage returns "Unexpected character"

Over about 200 queries to the moviedb, about 40 results came back with the "Unexpected character"

Is it possible to ignore this error, or at least determine what character the JSONErrorMessage is referring to?

Re: Json array question

Posted: Sat Oct 24, 2020 8:50 pm
by infratec
Please format the JSON$ so that I can use it directly in PB.
It costs to many time if every user who wants to help you have to do this for you.

And ...

these JSON$ looks different to what you provided first.

Code: Select all

{"page":1,"total_results":1,"total_pages":1,"results":
And ...

There are some additional characters:

12 and re

From where did they come?
If you remove them it will work.
It looks that your receive function is wrong.
You have to use

Code: Select all

ReturnValue = PeekS(Buffer, Size, #PB_UTF8|#PB_ByteLength)

Re: Json array question

Posted: Sat Oct 24, 2020 9:49 pm
by Evil1
Sorry, you are right. In my mind I was working on the same thing, but in reality I was working on parsing the movie titles, based on code I found on the german Purebasic forum :-

Code: Select all

InitNetwork()

EnableExplicit

Structure sMovie
  vote_average.i
  overview.s
  original_language.s
  release_date.s
  original_title.s
  backdrop_path.s
  popularity.i
  poster_path.s
  title.s
  adult.i
  vote_count.i
  id.i
  video.i
  List genre_ids.i()
EndStructure

Structure sSearchResult
  total_results.i
  total_pages.i
  page.i
  List results.sMovie()
EndStructure

Define Movies.sSearchResult
Define ReturnValue.s
Define Buffer, Size

Define Movie.s  = "Matrix"
Define ApiKey.s = "DeinKey"

Buffer = ReceiveHTTPMemory("http://api.themoviedb.org/3/search/movie?api_key=" + ApiKey + "&language=de&query=" + URLEncoder(Movie))

If Buffer
  Size = MemorySize(Buffer)
  ReturnValue = PeekS(Buffer, Size, #PB_UTF8)
  ParseJSON(0, ReturnValue)
  ExtractJSONStructure(JSONValue(0), @Movies.sSearchResult, sSearchResult)
  FreeJSON(0)
  ForEach Movies\results()
    Debug Movies\results()\title
  Next
  FreeMemory(Buffer)
Else
  Debug "Failed"
EndIf
I am trying to scan the themoviedb for film titles using this code to return the title Id and then use the second part of my program (first post) to retrieve the Genres etc.
This first part seemed to be working fine until I used it to scan through multiple entries. I was initially thinking the returned JSON errors were just problems in the returned data and not the application source code from the German forum. So my second post was asking about troubleshooting the formatting of the received JSON data as I didn't believe it was an issue with the Purebasic source code..

Sorry for the confusion, I thought I was just asking how to trouble shoot errors in the received JSON data in the belief that the source code from the German forum was not the issue.