json - 使用嵌套结构迭代 JSON
问题描述
我有一个具有以下结构的 JSON:
data": {
"password": {
"en": "Password",
"ar": "Password",
"zh": "Password",
...
},
"confirmPassword": {
"en": "Confirm password",
"ar": "Confirm password",
...
},
"addressInputStrings": {
"en": {
"search": "Address",
"placeholder": "Start typing your address",
"addressNotListed": "My address is not listed",
"country": "Country of residence",
"street": "Street",
...
}
"fileUploadStrings"
{
"en":
{
"required": "Please upload a document.",
"fileUploadSuccessful": "File uploaded successfully: ",
"uploadError": {
"multipartContentTypeError": "The request couldn't be processed (Error 1)",
...
基本上“数据”是根,它有许多属性,每个属性都有一个语言代码列表。该值通常是一个字符串。有时会有第二层嵌套,有时甚至是第三层。
我需要遍历 JSON 并获得以下输出
[key] (tab) [value of "en"]
如果 "en" 的值不是字符串而是另一个对象,那么
[key].[nested key (in "en")] (tab) [value]
如果还有另一层嵌套,那么
[key].[nested key (in "en")].[nested nested key] (tab) [value]
因此,对于示例,输出将如下所示:
password (tab) Passsword
confirmPassword (tab) Confirm password
addressInputStrings.search (tab) Address
addressInputStrings.addressInputStrings.placeholder (tab) Start typing your address
addressInputStrings.addressNotListed (tab) My address is not listed
addressInputStrings.country (tab) Country of residence
addressInputStrings.street (tab) Street
fileUploadStrings.required (tab) Please upload a document
fileUploadStrings.fileUploadSuccessful (tab) File uploaded successfully:
fileUploadStrings.uploadError.multipartContentTypeErrorThe (tab) request couldn't be processed (Error 1)
我认为使用 Newtonsoft.Json 会很容易,但这就像图书馆正在积极地与我作斗争。当我尝试在 JObject 上迭代子代时,我得到的是 Jproperties 而不是 JObjects,我希望在其中得到第一个子代,我再次得到整个集合,我不断地左右出现异常,我们不要忘记几乎没有任何东西想要评估当我在调试器中暂停时的 Watch 窗口,因此无法进行实验。唯一的选择是修改、构建、调试、出错、重复。
我能得到一个快速而肮脏的解决方案吗?谢谢你。
解决方案
听起来问题的根源在于您误解了 Json.Net 的LINQ-to-JSON API的设计。AJObject
永远不能直接包含另一个JObject
。AJObject
只包含JProperty
对象。每个JProperty
都有一个名称和一个值。a 的值JProperty
又可以是另一个JObject
(或者它可以是 aJArray
或JValue
)。有关层次结构中关系的更多信息,请参阅JContainer 、JObject、JToken 和 Linq 混淆的答案。JToken
了解了层次结构后,得到想要的输出的关键是Descendants()
扩展方法。这将允许您使用简单的循环进行递归遍历。为了得到你的输出,你基本上是在寻找整个 JSON中每个叶子的Path
和。您可以通过检查 是否为来识别叶子。Value
JProperty
Value
JValue
所以,把它们放在一起,这就是你的做法(我在这里假设 C#,因为你没有在你的问题中指定一种语言):
var root = JObject.Parse(json);
var leafProperties = root.Descendants()
.OfType<JProperty>()
.Where(p => p.Value is JValue);
foreach (var prop in leafProperties)
{
Console.WriteLine($"{prop.Path}\t{prop.Value}");
}
推荐阅读
- azure-devops - VSTS 中的可扩展敏捷结构
- c - 这个调用是引用还是 C 中的值?
- php - wordpress:在业务目录插件中搜索不起作用
- angular - 如何在 Angular4/TypeScript 中以编程方式打开 ng-datetime-picker 的选择对话框?
- docker - pod内的Kubernetes Docker进程
- python - Django - Gunicorn/Nginx - 502 错误网关
- typeahead.js - Typeahead Bloodhound 不过滤远程数据集
- php - SQLSTATE [HY000]:一般错误:1364 字段“已接受”没有默认值
- python - PyDev (Eclipse) 未处理的异常:“NoneType”对象没有属性“pydev_notify_kill”
- cordova - 如何找出旧项目的原始 IONIC 版本