【发布时间】:2016-07-27 02:54:27
【问题描述】:
我认为这个问题可能格式不正确,因此我创建了一个“姐妹”问题,该问题更加中肯,具体输出引用了该问题。请参阅: Querying JSON Nested Arrays with Linq, JSON.NET, C# 如果这个问题在这个问题之前得到回答,我将尝试使用来自另一个问题的信息自己回答这个问题...... :) 谢谢!
在上一个问题 (Picking Out Simple Properties from Hierarchical JSON) 中,我询问了如何从分层 JSON 中获取简单属性。那里的答案 [粘贴为本文末尾的 Linq 查询] 非常有用(并且,自从发布该消息以来,我已经研究了很多关于 Linq 和 JSON.NET 的知识)。所以我没有使用这个论坛,因为我很懒——当我真的陷入困境并且似乎无法在我可以访问的书籍中找到答案时,我会使用它。
我不知道如何继续我上一个问题提供的示例。这个问题建立在前一个问题的基础上,所以在这里(尽可能简洁地表达)是我很想学习如何在单个 Linq 查询中做的事情。
回顾一下:我正在使用这样的动态 JSON(它比我之前的第一部分中提出的 JSON 更复杂,因为它包含数组):
{
"Branch1": {
"Prop1A": "1A",
"Prop1B": "1B",
"Prop1C": "1C",
"Branch2": {
"Prop2A": "2A",
"Prop2B": "2B",
"Prop2C": "2C",
"Branch3": [{
"Prop3A": "3A",
"Prop3B": "3B",
"Prop3C": "3C"
}, {
"Prop3D": "3D",
"Prop3E": "3E",
"Prop3F": "3F"
}, {
"Prop3G": "3G",
"Prop3H": "3H",
"Prop3I": "3I"
}]
},
"Branch4": [{
"Prop4A": "4A",
"Prop4B": "4B",
"Prop4C": "4C"
}, {
"Prop4E": "4E",
"Prop4F": "4F",
"Prop4G": "4G"
}, {
"Prop4H": "4H",
"Prop4I": "4I",
"Prop4I": "4I"
}]
}
}
如您所见,动态 JSON 由分层对象组成,这些对象是 JSON 对象、JSON 数组和 JSON 属性。
最后,我想将此 JSON 转换为可以在 C# 中使用的 List 对象。我计划使用该 List 对象以从上到下的文档顺序有效地处理每个 JSON 分支。
List 集合中的每个项目都是一个 JObject;这些对象中的每一个都将具有一个合成的“父”字符串属性,该属性将指向该 JObject 在原始 JSON 中出现的分支(我下面的示例解释了我所说的“父”的含义)。 [上一个问题正确地提出了这个“父”值的解决方案,所以这与这个问题不太相关......这里的新/相关的是处理 JSON 中的 JArray 对象......]
关键是我希望每个列表项对象只包含该对象的字符串值属性。例如,Branch1 具有字符串属性 Prop1A、1B 和 1C。因此,我希望 query[0] 包含:
{"Prop1A":"1A","Prop1B":"1B","Prop1C":"1C", Parent:""}
接下来,我希望 query[2] 包含 Branch2 的字符串值属性:
{"Prop2A":"2A","Prop2B":"2B","Prop2C":"2C", Parent:"Branch1"}
接下来,我希望 query[2] 只包含 Branch3 的字符串属性,但由于 Branch3 是一个对象数组,我希望该数组最终一起出现在 query[2] 中:
[
{"Prop3A": "3A","Prop3B": "3B","Prop3C": "3C"},
{"Prop3D": "3D","Prop3E": "3E","Prop3F": "3F"},
{"Prop3G": "3G","Prop3H": "3H","Prop3I": "3I"}
]
请注意,此分支还没有对其“父级”的引用...我很高兴在 query[2] 中获得一个类似于上面的数组。 (我打算使用 dbc 的逻辑为每个数组元素添加一个“Parent”属性,或者想办法创建一个新的 JObject,其中包含该数组并只引用一次 Parent):
[{"Prop3A": "3A","Prop3B": "3B","Prop3C": "3C","Parent":"Branch2"},
{"Prop3D": "3D","Prop3E": "3E","Prop3F": "3F","Parent":"Branch2"},
{"Prop3G": "3G","Prop3H": "3H","Prop3I": "3I","Parent":"Branch2"}
]
所以,如你所见:
- 我希望任何不是数组的 JSON 分支都作为新的 JObject 插入到查询结果中,仅包含其字符串属性和对其父分支的引用。
- 我希望任何作为数组的 JSON 分支都作为新的 JObject 数组插入到查询结果中,并且只包含其字符串属性和对其父分支的引用。
我自己解决这个问题的麻烦在于弄清楚如何在 Linq 中创建“如果 myJsonObject 是 JArray”条件,并在分支不是数组时只分配字符串属性属性并迭代数组的当它是 JArray 时的元素。我怀疑我需要以某种方式利用 ? : 三元表达式,但我不知道该怎么做。
上一个问题的查询在这里:
var query3 = from o in root.DescendantsAndSelf().OfType<JObject>() // Find objects
let l = o.Properties().Where(p => p.Value is JValue) // Select their primitive properties
where l.Any() // Skip objects with no properties
// Add synthetic "Parent" property
let l2 = l.Concat(new[] { new JProperty("Parent", o.Ancestors().OfType<JProperty>().Skip(1).Select(a => a.Name).FirstOrDefault() ?? "") })
select new JObject(l2); // And return a JObject.
var list3 = query3.ToList();
该代码不以上述方式处理数组。
【问题讨论】:
-
您为
query[2]建议的JSON(简化为{ ["Prop3A": "3A"], "Parent": "Branch2" })无效。从standard 开始,JSON 容器要么是一个对象——一组被大括号包围的无序名称/值对,要么是一个数组——一组被方括号括起来的有序值。您提议的 JSON 有一个值,然后是一个名称/值对,所以两者都没有。上传到jsonlint.com你就会看到问题了。 -
很抱歉——我很累并且完全搞砸了 JSON(我通常使用 JSLint,但在这种情况下没有......)TY 并修复了问题......