在不知道完整结构的情况下反序列化 JSON
Deserialize JSON without knowing full structure
我正在重做一个非常 基本框架的后端,该框架连接到一个完全可定制的前端。它最初在 PHP 中,但重构一直在 F# 中缓慢进行。虽然看起来 PHP 可能是更合适的语言。但是人们一直告诉我,您可以在 F# 中做任何事情,我喜欢它的语法并且需要学习,而这个看似简单的项目让我在 JSON 方面感到困惑。这是我的 的进一步充实版本,但它比我想象的要复杂得多。
开始了。
前端基本上是 HTML 文件的集合,这些文件只是在 PHP 中加载, preg_replace() 用于替换 [var: varName] 或 [ var: array|key] 或麻烦的一个:[lang: hello]
。这需要用翻译词典中定义的变量替换,该变量存储为 JSON,非程序员也可编辑。
我无法更改前端或 JSON 文件,两者都是为非程序员编辑而设计的,因此很可能会有是错误,调用不存在的语言变量等
所以我们可能有 2 个 json 文件,english.json
和 french.json
english.json 包含:
{
"hello":"Hello",
"bye":"Goodbye"
}
french.json:
{
"hello": "Bonjour",
"duck": "Canard"
//Plus users can add whatever else they want here and expect to be able to use it in a template
}
有一个模板包含
<b>[lang: hello]</b>
<span>Favourite Animal: [lang:duck]</span>
在这种情况下,如果语言设置为“英语”并且正在加载 english.json,则应显示为:
<b>Hello</b>
<span>Favourite Animal: </span>
Or in French:
<b>Bonjour</b>
<span>Favourite Animal: Canard</span>
我们可以假设 json 格式 key: value
总是 string:string
但理想情况下我也想处理 string: 'T
但这可能超出了范围这个问题。
所以我需要转换一个 JSON 文件(通过动态名称调用,这给 F# Data 带来了一些我昨晚无法解决的问题,因为它只允许静态文件名作为示例,并且由于这两个文件可能与示例和提供的文件不同,类型提供程序不起作用)到字典或其他一些集合。
现在在模板解析函数中,我需要将 [lang: hello]
替换为
let key = "duck"
(*Magic function to convert JSON to usable collection*)
let languageString = convertedJSONCollection.[key] (*And obviously check if containsKey first*)
这意味着我需要动态调用密钥,但我不知道如何使用 FSharp.Data 提供的类型来实现。
我也尝试过一些 Thoth 以及一些有希望的结果,但最终无处可去。我避免了 JSON.NET 因为我认为它是付费的,但我才意识到我在那里弄错了所以可能有一条探索的途径
为了比较,PHP 函数看起来像这样:
function loadLanguage($lang='english){
$json = file_get_contents("$lang.json");
return json_decode($json, true);
}
$key = 'duck';
$langVars = loadLanguage();
$duck = $langVars[$key] || "";
在 F#/.NET 中是否有一种简洁的方法可以做到这一点?与 PHP/Javascript 相比,使用 JSON 似乎真的很痛苦,我开始失去理智了。我是否必须编写自己的解析器(这意味着可能要回到 PHP)?
为所有知道答案的 F# 天才干杯 :p
open Thoth.Json.Net
let deserialiseDictionary (s: string) =
s
|> Decode.unsafeFromString (Decode.keyValuePairs Decode.string)
|> Map.ofList
let printDictionary json =
json
|> deserialiseDictionary
|> fun m -> printfn "%s" m.["hello"] // Hello
对于关于'T 的问题,问题变成了'T 可以是什么?对于 json 它非常有限,它可以是一些东西,字符串,json-object,数字,bool 或者 json 数组。如果是 bool 或 number 会怎样?
我正在重做一个非常 基本框架的后端,该框架连接到一个完全可定制的前端。它最初在 PHP 中,但重构一直在 F# 中缓慢进行。虽然看起来 PHP 可能是更合适的语言。但是人们一直告诉我,您可以在 F# 中做任何事情,我喜欢它的语法并且需要学习,而这个看似简单的项目让我在 JSON 方面感到困惑。这是我的
开始了。
前端基本上是 HTML 文件的集合,这些文件只是在 PHP 中加载, preg_replace() 用于替换 [var: varName] 或 [ var: array|key] 或麻烦的一个:[lang: hello]
。这需要用翻译词典中定义的变量替换,该变量存储为 JSON,非程序员也可编辑。
我无法更改前端或 JSON 文件,两者都是为非程序员编辑而设计的,因此很可能会有是错误,调用不存在的语言变量等
所以我们可能有 2 个 json 文件,english.json
和 french.json
english.json 包含:
{
"hello":"Hello",
"bye":"Goodbye"
}
french.json:
{
"hello": "Bonjour",
"duck": "Canard"
//Plus users can add whatever else they want here and expect to be able to use it in a template
}
有一个模板包含
<b>[lang: hello]</b>
<span>Favourite Animal: [lang:duck]</span>
在这种情况下,如果语言设置为“英语”并且正在加载 english.json,则应显示为:
<b>Hello</b>
<span>Favourite Animal: </span>
Or in French:
<b>Bonjour</b>
<span>Favourite Animal: Canard</span>
我们可以假设 json 格式 key: value
总是 string:string
但理想情况下我也想处理 string: 'T
但这可能超出了范围这个问题。
所以我需要转换一个 JSON 文件(通过动态名称调用,这给 F# Data 带来了一些我昨晚无法解决的问题,因为它只允许静态文件名作为示例,并且由于这两个文件可能与示例和提供的文件不同,类型提供程序不起作用)到字典或其他一些集合。
现在在模板解析函数中,我需要将 [lang: hello]
替换为
let key = "duck"
(*Magic function to convert JSON to usable collection*)
let languageString = convertedJSONCollection.[key] (*And obviously check if containsKey first*)
这意味着我需要动态调用密钥,但我不知道如何使用 FSharp.Data 提供的类型来实现。
我也尝试过一些 Thoth 以及一些有希望的结果,但最终无处可去。我避免了 JSON.NET 因为我认为它是付费的,但我才意识到我在那里弄错了所以可能有一条探索的途径
为了比较,PHP 函数看起来像这样:
function loadLanguage($lang='english){
$json = file_get_contents("$lang.json");
return json_decode($json, true);
}
$key = 'duck';
$langVars = loadLanguage();
$duck = $langVars[$key] || "";
在 F#/.NET 中是否有一种简洁的方法可以做到这一点?与 PHP/Javascript 相比,使用 JSON 似乎真的很痛苦,我开始失去理智了。我是否必须编写自己的解析器(这意味着可能要回到 PHP)?
为所有知道答案的 F# 天才干杯 :p
open Thoth.Json.Net
let deserialiseDictionary (s: string) =
s
|> Decode.unsafeFromString (Decode.keyValuePairs Decode.string)
|> Map.ofList
let printDictionary json =
json
|> deserialiseDictionary
|> fun m -> printfn "%s" m.["hello"] // Hello
对于关于'T 的问题,问题变成了'T 可以是什么?对于 json 它非常有限,它可以是一些东西,字符串,json-object,数字,bool 或者 json 数组。如果是 bool 或 number 会怎样?