使用类型提供程序和 JSON API

Playing with Type Provider and JSON API

我正在尝试使用一个 API,其中 return 一个 JSON 构建为:

Team.player1 / player2 / player3...(球员是作为属性而不是数组构建的)

我想用反射来做,但是很难找到播放器。

type Simple = JsonProvider<"sample.json">

let wbReq = "API-FOR-TEAM"    

let docAsync = Simple.Load(wbReq)

let allValues = FSharpType.GetRecordFields (docAsync.Team.Players.GetType())
let test = allValues
            |> Seq.map (fun p -> (p.GetValue(docAsync.Team.Players) as ?).Name) // HOW TO GET THE TYPED PLAYER HERE ?
            |> fun p -> printfn p

编辑:我尝试使用 GetType 和 System.Convert.ChangeType

EDIT2:这是 JSON 的简化版本:

{
    "Team": {
        "id": "8",
        "players": {
            "17878": {
                "info": {
                    "idteam": 8,
                    "idplayer": 17878,
                    "note": 6
                }
            },
            "18507": {
                "info": {
                    "idteam": 8,
                    "idplayer": 18507,
                    "note": 5
                }
            }
        }
    }
}

编辑 3:

我在 C# 中找到了一个简单的解决方案(感谢 JSON.net 和动态),但出于学习目的,如果有人需要帮助,我想在 F# 中做同样的事情:

        private static List<Player> Parse(string jsonString)
        {
            dynamic jsonObject = JsonConvert.DeserializeObject(jsonString);

            var players = ParseItems(jsonObject.Home.players);

            return players;
        }

        private static List<Player> ParseItems(dynamic items)
        {
            List<Player> itemList = new List<Player>();
            foreach (var item in items)
            {
                itemList.Add(new Player()
                {
                    idplayer = item.Value.info.idplayer,
                    lastName = item.Value.info.lastname,
                    note = item.Value.info.note
                });
            }
            return itemList;
        }

您可以混合使用 JsonTypeProvider 和解析 Json。例如:

[<Literal>]
let sample = """{
    "Team": {
        "id": "8",
        "players": {
            "17878": {
                "info": {
                    "idteam": 8,
                    "idplayer": 17878,
                    "note": 6
                }
            },
            "18507": {
                "info": {
                    "idteam": 8,
                    "idplayer": 18507,
                    "note": 5
                }
            }
        }
    }
}"""

type Player = {IdTeam:int; IdPlayer:int; Note:int}

type Simple = JsonProvider<sample>
let docAsync = Simple.GetSample()

let json = docAsync.Team.Players.JsonValue

let parseInfo (json:JsonValue) = 

    let id_team = (json.GetProperty "idteam").AsInteger()
    let id_player = (json.GetProperty "idplayer").AsInteger()
    let note = (json.GetProperty "note").AsInteger()

    {IdTeam = id_team; IdPlayer = id_player; Note = note}

let players = 
    json.Properties()
    |> Array.map(fun (_,x) -> x.GetProperty "info")
    |> Array.map (parseInfo)

players
|> Array.iter (printfn "%A")