[英]Parsing Firebase JSON F#
I'm trying to convert the following Firebase JSON into something that can be parsed in F#
: 我正在尝试将以下Firebase JSON转换为可以在
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"
}
}
}
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. 这里的问题是第二行中的
L0pJmU9yj4hAocHjnrB
之类的条目以及后续的类似条目是在Firebase中创建的自动生成的时间戳ID,并且它们没有相应的名称,例如: "listing_id":"-L0pJmU9yj4hAocHjnrB"
,因此我愿意不知道如何设置我的F#
记录以正确解析此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
This produces the following output: 这将产生以下输出:
{declined = null;
matches = null;
search_settings = null;
listings = Some {listing_id = null;
location = null;
messages = null;};}
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. 如我们所见,第一个
listings
标记已正确反序列化,但是一旦看到L0pJmU9yj4hAocHjnrB
它就不知道那是什么,其余解析失败。 How can I fix this issue? 如何解决此问题?
You can deserialize your JSON with the following F# types: 您可以使用以下F#类型反序列化JSON:
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
}
And the following line of code: 和下面的代码行:
let listings_json = JsonConvert.DeserializeObject<UserContent>(inputJson)
Notes: 笔记:
The "listing"
object consists of variable property names with a fixed schema for their values. "listing"
对象由变量属性名称和值的固定模式组成。 As explained in Serialization Guide: Dictionaries and Hashtables such objects can be mapped to a .Net dictionary. 如《 序列化指南:词典和哈希表》中所述,此类对象可以映射到.Net词典。 In this case I chose the F#
Collections.Map<'Key,'Value>
class, specifically a Map<string, ListingContent>
. 在这种情况下,我选择了F#
Collections.Map<'Key,'Value>
类,特别是Map<string, ListingContent>
。
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>>
. 类似地,
"messages"
对象由变量属性名称组成,其值是具有变量属性名称的对象的嵌套级别,因此可以用Map<string, Map<string, MessageContent>>
。
I simplified the UserContent
and ListingContent
types by removing members not actually present in the sample JSON. 通过删除示例JSON中实际不存在的成员,我简化了
UserContent
和ListingContent
类型。 You can add them back as required. 您可以根据需要将它们添加回去。
Since Json.NET has built-in support for dictionaries, a custom JsonConverter
is not required for this solution. 由于Json.NET具有对字典的内置支持,因此此解决方案不需要自定义
JsonConverter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.