F#: Как получить доступ к элементам перечисленным способом из файла JSON?
Мне нравятся поставщики типов F#, и именно поэтому я стараюсь использовать FSharp.Библиотека данных, когда я могу, но я нашел вариант использования,который не кажется покрытым.
Рассмотрим этот простой файл JSON:
{
"Foo": {
"Baz": 0,
"Bazz": "x"
},
"Bar": {
"Baz": 10,
"Bazz": "y"
}
}
Я хочу разобрать элементы выше как массив, а не обращаться к элементам Foo и Bar жестко. То есть, получая IEnumerable<SomeRecord>
, где SomeRecord имеет 2 члена Baz
и Bazz
. Можно ли каким-то образом использовать API JsonProvider для достижения этой цели?
Я попробовал SampleIsList=true
вариант, но, кажется, не работает:
type MyJsonProvider = JsonProvider<"./elements.json",
EmbeddedResource="MyAssemblyName, elements.json",
SampleIsList=true>
let SomeReadingMethod() =
let assembly = Assembly.GetExecutingAssembly()
let embeddedServerListFileName = "elements.json"
use stream = assembly.GetManifestResourceStream(embeddedServerListFileName)
use reader = new StreamReader(stream)
let list = reader.ReadToEnd()
let elements = MyJsonProvider.Parse(list)
for element in elements do
...
Я получаю ошибку компилятора: The type JsonProvider<...>.Root is not a type whose values can be enumerated with this syntax...
1 ответ:
Можно ли каким-то образом использовать API JsonProvider для достижения этой цели?
Нет, вводимый вами пример-этоКарта от ключей/полей до значений, а не перечисление значений.
SampleIsList
предназначен для случаев, когда сам образец представляет собой коллекцию, содержащую несколько экземпляров типа, который вы предполагаете. Если вы хотите использоватьJsonProvider
с этим, я думаю, вам нужно будет изменить свою схему JSON как во время разработки, так и во время выполнения.В качестве альтернативы я бы рассмотрел написание простого синтаксического анализатора, либо с использованием функций JSON parsing в FSharp.Data или одна из других библиотек синтаксического анализа OSS F# JSON. Вот рудиментарный пример:
open FSharp.Data open FSharp.Data.JsonExtensions let info = JsonValue.Parse(""" { "Foo": { "Baz": 0, "Bazz": "x" }, "Bar": { "Baz": 10, "Bazz": "y" } } """) type MyRecord = { Baz : int; Bazz : string } let parse props = seq { for (_k,v) in props -> {Baz = v?Baz.AsInteger(); Bazz = v?Bazz.AsString()} } > parse info.Properties;; val it : seq<MyRecord> = seq [{Baz = 0; Bazz = "x";}; {Baz = 10; Bazz = "y";}]