【问题标题】:Retrieve all JSON key's values from JSON without known structure从没有已知结构的 JSON 中检索所有 JSON 键的值
【发布时间】:2020-10-08 08:56:50
【问题描述】:

我从某个端点获取 JSON,我只知道它将包含名为“x”的数组,它可以包含所有内容(另一个数组、JSON 属性等)。

现在,我想从所有键中检索值并将其连接成一个字符串。

我找到了这个solution,但是当它遇到属性数组时,它会按原样给我,就像这样:

"test": {
      "test1": "tea",
      "test2": "tt",
      "foo": "",
      "bar": "48f7c3284ca0",
      "random": "Harry",
      "anything": "Potter"
    },

我想从上面仅检索值并将它们连接成字符串,如下所示:

“茶 tt 48f7c3284ca0 哈利波特”。

换句话说 - 我想foreach generic JSON 中的每个键,如果它没有子项,则获取它的值并保持 foreaching。

【问题讨论】:

  • 只枚举test节点的属性值
  • 您应该提供一段特定的 JSON,涵盖所有种预期输入/输出

标签: c# json .net json.net


【解决方案1】:
private static IEnumerable<string> Flat(JToken token)
    {
        switch (token.Type)
        {
            // nested value types
            case JTokenType.Object:
            case JTokenType.Array:
            case JTokenType.Property:
                foreach (var item in token.Children().Select(Flat).SelectMany(x => x))
                    yield return item;
                break;
            default: // primitive values: int, string, float
                yield return token.ToString();
                break;
        }
    }

    static async Task Main(string[] args)
    {
        JToken token = Newtonsoft.Json.JsonConvert.DeserializeObject<JToken>(File.ReadAllText("test.json"));
        foreach (var item in Flat(token))
        {
            Console.WriteLine(item);
        }
    }

这是测试输出 https://ctrlv.cz/TvqP

【讨论】:

    【解决方案2】:

    你可以使用类似的东西(如果字段是原始类型):

                dynamic stuff = JsonConvert.DeserializeObject("{'test1':'tea','test2':'tt','foo':'','bar':'48f7c3284ca0','random':'Harry','anything':'Potter'}");
    
                List<string> resultValues = new List<string>();
                foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(stuff))
                {
                    resultValues.Add(prop.GetValue(stuff).ToString());
                }
    

    【讨论】:

      【解决方案3】:

      我会通过原始字符串进行正则表达式:

      (\s*:\s*"?)(\s*[\w\.]*)("?\s*)

      每个匹配项都具有第 2 组中的值。

      演示在这里(它还提供了正则表达式的分解):https://regex101.com/r/Nh7bTS/

      演示中使用的 JSON 如下:

      {
        test: {
          "emptystr": "",
          "str": "p",
          "num": 6,
          "obj": {
            "k20": {
              "k200": "uz"
            }
          },
          "arr": [ 2, 3, 4 ],
          "str1": "  asd",
          "num1": 0.33445,
        }
      }
      

      深度无关紧要,只要输入是有效的 JSON。

      必须过滤匹配列表以排除第 1 组等于 : 的所有匹配(这意味着该值既不是字符串也不是数字)。

      【讨论】:

      • Regex 听起来不错,但在您提供的演示中,并非所有值都匹配。例如,obj.k20.k200 有 "uz" 值并且不匹配:/
      • 这与问题的要求有很大不同。让我们看看...
      • 谢谢亚历克斯,虽然我选择了其他答案,但你的也很棒。
      猜你喜欢
      • 1970-01-01
      • 2019-11-11
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-08
      相关资源
      最近更新 更多