【问题标题】:Picking Out Simple Properties from Hierarchical JSON Part II从分层 JSON 第二部分中挑选出简单的属性
【发布时间】: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 并修复了问题......

标签: c# linq json.net


【解决方案1】:

我的相关帖子中有效地出现了对这个问题的合适且更一般的答案: Picking Out Simple Properties from Hierarchical JSON

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多