json - 在不知道完整结构的情况下反序列化 JSON
问题描述
我正在重做一个非常基本的框架的后端,该框架连接到一个完全可定制的前端。它最初是在 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"
}
法语.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”并且正在加载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 提供的类型来做到这一点。
我也玩过一些透特,以及一些有希望的结果,但最终无济于事。我避免使用 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”的问题,问题变成了“不可能是什么”?对于 json 它非常有限,它可以是许多东西,字符串、json-object、数字、bool 或 json 数组。如果它是 bool 或 number 会发生什么?
推荐阅读
- pandas - Unable to import Pandas because of Numpy
- php - DOMDocument::loadXML(): I/O 警告:加载外部实体失败
- python - 从 wikisource XML 转储文件中提取文本
- python-3.x - 如何将 AWS Glue df 列数据写入单独的 html 文件
- python - 无法更新模型,因为“id 已存在”
- javascript - Ant Design 在 react js 项目中不起作用
- java - 方法调用“getMessage”可能会产生“NullPointerExeption”
- java - 休眠在数据库端设置默认值的正确方法
- javascript - REACT JS:TypeError:无法读取未定义的属性“参数”
- jmeter - 使用 MQTT 发布者通过 Jmeter 连接到 TLS