解析Firebase JSON F# [英] Parsing Firebase JSON F#

查看:152
本文介绍了解析Firebase JSON F#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将以下Firebase JSON转换为可以在F#中解析的内容:

I'm trying to convert the following Firebase JSON into something that can be parsed in F#:

{  
   "listings":{  
      "-L0pJmU9yj4hAocHjnrB":{  
         "listing_id":"-L0pJmU9yj4hAocHjnrB",
         "location":"Edinburgh",
         "messages":{  
            "SWs56OIGzMdiCjSXahzDQX8zve92":{  
               "-L3ELSSzZPRdjCRcFTrb":{  
                  "senderId":"SWs56OIGzMdiCjSXahzDQX8zve92",
                  "senderName":"alberto",
                  "text":"Hi"
               },
               "-L3EN1NW5hHWBTEGC9ve":{  
                  "senderId":"YMM45tgFFvYB7rx9PhC2TE5eW6D2",
                  "senderName":"David",
                  "text":"Hey"
               }
            }
         }
      },
      "-L19C5OjcDSjMi4-oha-":{  
         "listing_id":"-L19C5OjcDSjMi4-oha-",
         "location":"Edinburgh"
      },
      "-L19CJrzEpChO_W14YkC":{  
         "listing_id":"-L19CJrzEpChO_W14YkC",
         "location":"Edinburgh",
         "messages":{  
            "Rp7ytJdEvZeMFgpLqeCSzkSeTyf1":{  
               "-L19V4QpPMCMwGcNaQBG":{  
                  "senderId":"Rp7ytJdEvZeMFgpLqeCSzkSeTyf1",
                  "senderName":"Albert",
                  "text":"Hey there"
               },
               "-L19r0osoet4f9SjBGE7":{  
                  "senderId":"YMM45tgFFvYB7rx9PhC2TE5eW6D2",
                  "senderName":"David",
                  "text":"Hi"
               },
               "-L3ELGAbcOjdJsHRtnAe":{  
                  "senderId":"YMM45tgFFvYB7rx9PhC2TE5eW6D2",
                  "senderName":"David",
                  "text":"Icvjv"
               }
            }
         }
      },
      "-L19ChjPjX1DnfQb28AW":{  
         "listing_id":"-L19ChjPjX1DnfQb28AW",
         "location":"Edinburgh",
         "messages":{  
            "879dUqGuiXSd95QHzfhbSs05IZn2":{  
               "-L1i6c7sGf3BcF2cCSCu":{  
                  "senderId":"879dUqGuiXSd95QHzfhbSs05IZn2",
                  "senderName":"Alberto",
                  "text":"Hello"
               }
            },
            "Rp7ytJdEvZeMFgpLqeCSzkSeTyf1":{  
               "-L19FGCMuQACjYKCFEwV":{  
                  "senderId":"Rp7ytJdEvZeMFgpLqeCSzkSeTyf1",
                  "senderName":"Albert",
                  "text":"Hey"
               },
               "-L19T_v2Utxhu1mGhz7-":{  
                  "senderId":"YMM45tgFFvYB7rx9PhC2TE5eW6D2",
                  "senderName":"David",
                  "text":"Hi"
               },
               "-L19TbhActGmga4f47Mz":{  
                  "senderId":"Rp7ytJdEvZeMFgpLqeCSzkSeTyf1",
                  "senderName":"Albert",
                  "text":"How are you"
               }
            }
         }
      },
      "-L19Cz1abm1o-JCbiAnN":{  
         "listing_id":"-L19Cz1abm1o-JCbiAnN",
         "location":"Edinburgh"
      },
      "-L19DMdFx2pXj9-EKCq2":{  
         "listing_id":"-L19DMdFx2pXj9-EKCq2",
         "location":"Edinburgh"
      },
      "-L19DV67WjguozFE_4dM":{  
         "listing_id":"-L19DV67WjguozFE_4dM",
         "location":"Edinburgh"
      }
   }
}

这里的问题是第二行中的L0pJmU9yj4hAocHjnrB之类的条目以及后续的类似条目是在Firebase中创建的自动生成的时间戳ID,并且它们没有对应的名称,例如:"listing_id":"-L0pJmU9yj4hAocHjnrB",因此我这样做不知道如何设置我的F#记录以正确解析此JSON.

The problem here is that the entries like L0pJmU9yj4hAocHjnrB in the 2nd line and subsequent similar entries are autogenerated timestamp IDs created in Firebase, and they do not have a corresponding name, like for example: "listing_id":"-L0pJmU9yj4hAocHjnrB", therefore I do not know how to set up my F# Records to correctly parse this JSON.

我的尝试可以在下面看到:

My attempt can be seen below:

type MessageContent = 
    { senderId: string
      senderName: string
      text: string; }

type Message =
     { timestampId : string
       chatMessages : MessageContent;}

type Chat = 
    { chatPartnerId : string 
      Messages : Message array option;}

type ListingContent = 
    { from : string
      landlord_id : string
      listing_id : string
      location : string
      name : string
      pic_1_url : string
      pic_2_url : string
      pic_3_url : string
      pic_4_url : string
      pic_5_url : string
      messages : Chat array option
      postcode : string
      price_per_night : int
      to_date : string;
    }

type Listing =
     { timestampId : string
       listingcontent : ListingContent option;}

type City = 
    { city : string
      listings : Listing array option
    }

type AllListings = 
    { cities : City array;}

type SearchSettings = 
    { from : string
      location : string
      max_price : decimal
      min_price : decimal
      to_date : string;}

type MatchContent = 
    { id : string
      location : string;}

type Match = 
    {timestampId : string
     matchContent : MatchContent;}

type DeclinedContent = 
    { id : string;
      }

type Declined = 
    {timestampId : string
     declinedContent : DeclinedContent;}

type ListingUserContent = 
    { listing_id : string
      location : string
      messages : Chat array option;
    }

type ListingUser = 
    {timestampId : string
     listingUser : ListingUserContent;}

type UserContent = 
    { declined: Declined option
      matches : Match option
      search_settings : SearchSettings option
      listings : ListingUser option;
    }

我使用以下代码进行解析:

I use the following code for parsing:

    let myCallbackGetChats (reader:IO.StreamReader) url = 
    let html = reader.ReadToEnd()
    let reader = new JsonTextReader(reader);
    let serializer = JsonSerializer.Create(JsonSerializerSettings(Converters = [| Types.OptionConverter() |]))
    use stringReader = new StringReader(html)
    use jsonReader = new JsonTextReader(stringReader)
    let listings_json = serializer.Deserialize<Types.UserContent>(jsonReader)
    printfn "%A" listings_json

这将产生以下输出:

    {declined = null;
 matches = null;
 search_settings = null;
 listings = Some {listing_id = null;
                  location = null;
                  messages = null;};}

正如我们看到的那样,第一个listings标记已正确反序列化,但是一旦看到L0pJmU9yj4hAocHjnrB,它就不知道它是什么,其余解析失败.我该如何解决这个问题?

As we can see the first listings tag is properly deserialized, however as soon as it sees L0pJmU9yj4hAocHjnrB it doesn't know what that is and the rest of the parsing fails. How can I fix this issue?

推荐答案

您可以使用以下F#类型反序列化JSON:

You can deserialize your JSON with the following F# types:

type MessageContent = 
    { senderId: string
      senderName: string
      text: string; 
    }

type ListingContent = 
    { listing_id : string
      location : string
      messages : Map<string, Map<string, MessageContent>>
      // Add other members as required
    }

type UserContent =
    { listings: Map<string, ListingContent>
      // Add other members as required
    }

以及以下代码行:

let listings_json = JsonConvert.DeserializeObject<UserContent>(inputJson)

注意:

  • The "listing" object consists of variable property names with a fixed schema for their values. As explained in Serialization Guide: Dictionaries and Hashtables such objects can be mapped to a .Net dictionary. In this case I chose the F# Collections.Map<'Key,'Value> class, specifically a Map<string, ListingContent>.

类似地,"messages"对象由可变属性名称组成,其值是具有可变属性名称的对象的嵌套级别,因此可以用Map<string, Map<string, MessageContent>>表示.

Similarly, the "messages" object consists of variable property names whose values are a nested level of objects with variable property names, and so can be represented with a Map<string, Map<string, MessageContent>>.

我通过删除示例JSON中实际不存在的成员简化了UserContentListingContent类型.您可以根据需要将它们重新添加.

I simplified the UserContent and ListingContent types by removing members not actually present in the sample JSON. You can add them back as required.

由于Json.NET具有对字典的内置支持,因此此解决方案不需要自定义JsonConverter.

Since Json.NET has built-in support for dictionaries, a custom JsonConverter is not required for this solution.

工作示例 F#小提琴.

这篇关于解析Firebase JSON F#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆