Worice Worice - 7 days ago 6
JSON Question

Operations on JSON-structured data

I would like to parse JSON-structured data contained in a

.txt
file. I correctly installed the
FSharp.Data
library, and set up the paths (I am still learning relative paths). Even so it throws an error that I cannot interpret.

#r "C:/Users/mauri/OneDrive/Programmazione1/Sharpstone/dataAccessManipulation/
packages/FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll";;
open FSharp.Data
open FSharp.Data.JsonExtensions
let value = JsonValue.Load("C:/Users/mauri/OneDrive/Programmazione1/Sharpstone/SharpStone/Deck1")


Think of a simple operation as printing all the contents of the tag
collection


for col in value?collectible do
printfn "%s" (col.AsString())

System.Exception: Not an object


This operation works on smaller pieces of data such the ones from the tutorial. Unfortunately, I still cannot make it work on a larger database (since it is quite heavy to the sight, please find it on my GitHub account ). What is the reason of such an error, and what does "not an object" mean?

Answer

The error message "Not an object" means that you are trying to access a property of a JSON node that is not an object (with fields) but something else - such as collection.

Using the sample deck from GitHub, I suppose that value represents a collection and so writing value?collectible will give you this error - because you are trying to access a property collectible of something that is a collection.

The following (printing all artist names) should work:

let value =  JsonValue.Load("https://raw.githubusercontent.com/Maurizio-Mario/Sharpstone/master/SharpStone/deck1.txt")

for col in value.AsArray() do
  if col?collectible.AsBoolean() then
    printfn "%s" (col?artist.AsString())

That said, it is much easier to use the JSON type provider, which infers the type of the JSON document from a sample and then exposes all the properties in a type safe way:

 type Deck = JsonProvider<"https://raw.githubusercontent.com/Maurizio-Mario/Sharpstone/master/SharpStone/deck1.txt">
let value = Deck.GetSamples()

for col in value do
  if col.Collectible then
    printfn "%s" col.Artist
Comments