解析Firebase JSON F# [英] Parsing 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)
注意:
-
"listing"
对象由具有固定值格式的变量属性名称组成.如 序列化指南:字典和哈希表中所述这样的对象可以映射到.Net词典.在这种情况下,我选择了F#
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 aMap<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中实际不存在的成员简化了UserContent
和ListingContent
类型.您可以根据需要将它们重新添加.
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屋!