4

Is it possible to get property from JSON using complex path, like "prop1.prop2"? Sample of JSON I used:

{
    "prop1": {
        "prop2": "value"
    }
}

What I have want is to get property "prop2" there with its value "value": When I tried:

#r "../packages/FSharp.Data.2.3.0/lib/net40/FSharp.Data.dll"
open FSharp.Data
open FSharp.Data.JsonExtensions

let json = JsonValue.Load "SampleJson.json"
json.GetProperty("prop1.prop2")

I got:

System.Exception: Didn't find property 'prop1.prop2' in {"prop1":{"prop2":"value"}}

I tried to write such method by my own, but it looks clumsy:

let rec tryGetChildValue (propNameSplitted : List<string>) (json:JsonValue) = 
    match propNameSplitted with
    | [] -> None
    | [x] -> json.TryGetProperty (x)
    | x::xs -> 
        match json.TryGetProperty (x) with
        | Some p -> tryGetChildValue xs (json.GetProperty(x))
        | None -> None

let tryGetPropValue (propName: string) (json:JsonValue) = 
    let s = propName.Split '.' |> Array.toList
    tryGetChildValue s json

let propName = "prop1.prop2"
let result = (tryGetPropValue propName json)
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
Alex Klunniy
  • 125
  • 1
  • 8

2 Answers2

6

You can do that trivially with JSON.net:

open Newtonsoft.Json.Linq

let query json =
    let j = JObject.Parse json
    j.SelectToken "prop1.prop2" |> string

Obviously, there's no type safety with this approach, but that's the trade-off if you want to be able to query using arbitrary strings.

Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
5

Inside FSharp.Data, you can find a JSonProvider that allows you to get properties ( and more if you want) from a JSON object using complex path. You can do something like this and it should work for you:

type test =  FSharp.Data.JsonProvider<"""{
    "prop1": {
        "prop2": "value"
    }
} """>

let testSample = test.GetSample()

let testValue = testSample.Prop1.Prop2

and you will have the returned value to be : val testValue : string = "value"

You have to be carefull that what you give as a parameter to the JSonProvider is a String representation of your Json object.

I hope that helps :)

Leleutch
  • 215
  • 1
  • 6
  • Thanks Leleutch. I tried JsonProvider. But my problem is that I need to access JSON dynamically, so what I really have is JSON file and path to JSON token (that I do not know beforehand). So, unfortunately, I could not code as you suggest. What I actually searched was similar to this http://stackoverflow.com/questions/19645501/searching-for-a-specific-jtoken-by-name-in-a-jobject-hierarchy – Alex Klunniy May 21 '16 at 20:29