如何为Json.net生成json对象的所有可能的LINQ字符串?

时间:2016-07-19 16:16:42

标签: c# json linq json.net

在json.net中,我们可以使用基于this tutorial的linq到json。

我想知道有没有办法生成字符串查询?考虑一下这个json示例:

{
  "Name": "Test",
  "Status": [
    "S1",
    "S2",
    "S3",
    "S4"
  ],
  "People": [
    {
      "Name": "A",
      "Family": "AA",
      "Addresses": [
        {
          "Country": "A2",
          "City": "A1",
          "Phones": [
            "A3",
            "A4",
            "A5"
          ]
        }
      ]
    },
    {
      "Name": "B",
      "Family": "BB",
      "Addresses": [
        {
          "Country": "B2",
          "City": "B1",
          "Phones": [
            "B3",
            "B4",
            "B5"
          ]
        }
      ]
    },
    {
      "Name": "C",
      "Family": "CC",
      "Addresses": [
        {
          "Country": "C2",
          "City": "C1",
          "Phones": [
            "C3",
            "C4",
            "C5"
          ]
        },
        {
          "Country": "C7",
          "City": "C6",
          "Phones": [
            "C8",
            "C9",
            "C10"
          ]
        }
      ]
    }
  ]
}

我手写了所有可能的LINQ字符串:

// JSON.NET Linq Strings (by HAND)

"Name"
"Status[0]"
"Status[1]"
"Status[2]"
"Status[3]"
"People[0].Name"
"People[0].Family"
"People[0].Addresses[0].City"
"People[0].Addresses[0].Country"
"People[0].Addresses[0].Phones[0]"
"People[0].Addresses[0].Phones[1]"
"People[0].Addresses[0].Phones[2]"
"People[1].Name"
"People[1].Family"
"People[1].Addresses[0].City"
"People[1].Addresses[0].Country"
"People[1].Addresses[0].Phones[0]"
"People[1].Addresses[0].Phones[1]"
"People[1].Addresses[0].Phones[2]"
"People[2].Name"
"People[2].Family"
"People[2].Addresses[0].City"
"People[2].Addresses[0].Country"
"People[2].Addresses[0].Phones[0]"
"People[2].Addresses[0].Phones[1]"
"People[2].Addresses[0].Phones[2]"
"People[2].Addresses[1].City"
"People[2].Addresses[1].Country"
"People[2].Addresses[1].Phones[0]"
"People[2].Addresses[1].Phones[1]"
"People[2].Addresses[1].Phones[2]"

我尝试编写一些代码来自动创建所有可能的字符串:

        var dic = new Dictionary<string, string>();
        var json = JsonConvert.SerializeObject(obj, new JsonSerializerSettings() { Formatting = Formatting.Indented });
        JObject linq = JObject.Parse(json);
        foreach (var x in linq) // DOES NOT WORK FOR CHILDREN ?????!!!!! 
        {
            string name = x.Key;
            JToken value = x.Value;
            if (value.HasValues) // Array
            {                   
                var counter = 0;
                foreach (var item in value.Values())
                {
                    dic.Add(name + $"[{counter}]", item.ToString());
                    counter++;
                }
            }
            else // String
            {
                var v = value.ToString();
                dic.Add(name, v);
            }
        }

但是,我不知道如何为所有孩子写它。有什么帮助吗?

1 个答案:

答案 0 :(得分:3)

您可以使用SelectTokens("..*")以递归方式下降JSON令牌层次结构,其中".."是<{3}} 递归下降运算符,而"*"是通配符匹配任何东西。然后,您可以使用JSONPath作为词典键:

var dic = linq.SelectTokens("..*")
    .ToDictionary(t => t.Path, t => t.ToString());

请注意,这包括根令牌。如果你想跳过它,请执行:

var dic = linq.SelectTokens("..*")
    .Where(t => t != linq)
    .ToDictionary(t => t.Path, t => t.ToString());

您还可以使用JToken.PathJContainer.DescendantsAndSelf()进行递归下降,过滤掉所有JProperty个节点以获得相同的结果:

var dic = linq.Descendants()
    .Where(t => t.Type != JTokenType.Property)
    .ToDictionary(t => t.Path, t => t.ToString());