使用Type Provider和JSON API

时间:2017-02-07 17:13:11

标签: c# json f# type-providers f#-data

我正在尝试使用返回构建为:

的JSON的API

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;
        }

1 个答案:

答案 0 :(得分:1)

您可以混合使用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")
相关问题