在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);
}
}
但是,我不知道如何为所有孩子写它。有什么帮助吗?
答案 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.Path
或JContainer.DescendantsAndSelf()
进行递归下降,过滤掉所有JProperty
个节点以获得相同的结果:
var dic = linq.Descendants()
.Where(t => t.Type != JTokenType.Property)
.ToDictionary(t => t.Path, t => t.ToString());