使用LINQ解析唯一集合到JSON
本文关键字:集合 JSON 唯一 LINQ 使用 | 更新日期: 2023-09-27 18:16:19
我正在尝试使用LINQ解析JSON提要,并且无法将对象/值列表包装成合理的类。
我的JSON看起来像:
{
"Project":[
{
"ID":"XY1212",
"Name":"Some Name",
"Description":"U.S. No 2 Diesel Retail Prices",
"Manager":"Nora Sims",
"Dept":"HR",
"Updated":"2014-07-22",
"Statistics":[
[
"20140722",
32.22
],
[
"20140721",
55
],
[
"20140720",
343
],
[
"20140519",
43
],
[
"20140421",
3.971
],
[
"20140211",
40.2
],
[
"20140210",
17
],
[
"20140209",
16
]
]
}
]
}
从上面的JSON中,我有以下类结构:
public class Project
{
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Manager { get; set; }
public string Dept { get; set; }
public string Updated { get; set; }
public List<List<object>> Statistics { get; set; }
}
public class RootObject
{
public List<Project> Project { get; set; }
}
public class Statistic
{
public Datetime ProjectDate { get; set; }
public Decimal Sale { get; set; }
}
我试图解析的饲料,只是想要的"统计"数据,但不确定如何得到所有的值到"统计"的集合:
HttpClient() http = new HttpClient();
var json = await http.GetStringAsync(uri);
JObject jo = JObject.Parse(json);
var jList = from values in jo["Project"].Children()["Statistics"]
select values;
当我通过以下循环检查jList时:
foreach (var stat in jList)
{
Console.WriteLine(stat);
}
我可以"看到"所有的值,但它只循环一次,即jList只是一个大的[0],"值"是所有的[x, y], [x1, y1],…,即看起来像一个一维数组,其中包含许多二维数组。
我想循环遍历所有的"数组",我相信这就是它们的含义,在我在调试时在Visual Studio中看到的[0]内。
欢迎指教
您可以通过为您的Statistic
类创建自定义JsonConverter
来轻松解决这个问题。它将处理非常规的JSON,并允许您以您真正喜欢的方式定义项目类。
class StatisticConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Statistic));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray array = JArray.Load(reader);
return new Statistic
{
ProjectDate = DateTime.ParseExact(array[0].ToString(), "yyyyMMdd",
System.Globalization.CultureInfo.InvariantCulture),
Sale = array[1].ToObject<decimal>()
};
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用转换器,我们只需要对你的类做一些小的改变。首先,将Statistics
属性更改为List<Statistic>
而不是List<List<object>>
。(不要担心它与JSON不匹配——这就是转换器的作用。)
public class Project
{
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Manager { get; set; }
public string Dept { get; set; }
public string Updated { get; set; }
public List<Statistic> Statistics { get; set; }
}
接下来用[JsonConverter]
属性装饰Statistic
类,将其绑定到自定义转换器:
[JsonConverter(typeof(StatisticConverter))]
public class Statistic
{
public DateTime ProjectDate { get; set; }
public Decimal Sale { get; set; }
}
就是这样!现在,您可以按正常方式反序列化,并且您将获得您想要的统计数据列表。
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
问题不在于您的代码,而在于从HttpClient返回的JSON字符串。因为它有没有键的部分,所以很难排序,而且statistic的每个子函数都是那个子函数的子函数(如果我的眼睛没有欺骗我的话)。
但是,使用下面的代码,我能够读取Statistics值。
JObject jo = JObject.Parse(json);
var jList = from values in jo["Project"]
select values;
foreach (var j in jList)
{
var l = j["Statistics"].Children();
foreach (var m in l.Children())
{
string a = m.ToString();
}
}
在第一个循环中,m有Date,在第二个循环中,它有sale。因为没有键,所以我不知道有什么其他的方法来引用它们。
代码少一点,但结果相似
JObject jo = JObject.Parse(json);
for (int i = 0; i < jo.Count; i++)
{
var jList = from values in jo["Project"][i]["Statistics"]
select values;
foreach (var stat in jList)
{
//here stat looks like {["20140722", 32.22]}
}
}