如何在C#中过滤JSON数组

我花了很多时间为我的问题找到解决方案。

在这个例子中,我在SetNavRecords数组中有2条记录。 第一个是“Artikelnummer”:“21700” ,第二个是“Artikelnummer”:“21701”

每条记录都有一个数组“OfflineVerkaufspreis”。

对我来说重要的是“OfflineVerkaufspreis”中的“Location_Code”字段我只需要一个已过滤的位置代码的孔信息。

如何选择一个位置代码的数据,例如“MH”?

我正在使用C#和Newtonsoft类进行JSON解析。

我用LINQ尝试了一些版本但没有成功。

{ "SetNavRecords" : [ { "Artikelbeschreibung" : "Trikot \"Home\" 2012/2013", "Artikelbeschreibung2" : "weiß", "Artikelnummer" : "21700", "Artikelrabattgruppe" : "MERCH", "Gutschein" : false, "MwStProduktgruppe" : "VOLLNEU", "OfflineVerkaufspreis" : [ { "Allow_Line_Discount" : true, "Date" : "2014-05-16T00:00:00", "Item_No" : "21700", "Location_Code" : "BP", "Unit_Price" : 5.0 }, { "Allow_Line_Discount" : true, "Date" : "2014-05-16T00:00:00", "Item_No" : "21700", "Location_Code" : "MH", "Unit_Price" : 5.0 }, { "Allow_Line_Discount" : true, "Date" : "2014-05-16T00:00:00", "Item_No" : "21700", "Location_Code" : "RY", "Unit_Price" : 5.0 } ] }, { "Artikelbeschreibung" : "Autogrammtrikot 2012/2013", "Artikelbeschreibung2" : "weiß", "Artikelnummer" : "21701", "Artikelrabattgruppe" : "MERCH", "Gutschein" : false, "MwStProduktgruppe" : "VOLLNEU", "OfflineVerkaufspreis" : [ { "Allow_Line_Discount" : false, "Date" : "2014-05-16T00:00:00", "Item_No" : "21701", "Location_Code" : "BP", "Unit_Price" : 69.99 }, { "Allow_Line_Discount" : false, "Date" : "2014-05-16T00:00:00", "Item_No" : "21701", "Location_Code" : "MH", "Unit_Price" : 69.99 }, { "Allow_Line_Discount" : false, "Date" : "2014-05-16T00:00:00", "Item_No" : "21701", "Location_Code" : "RY", "Unit_Price" : 69.99 } ] } ] } 

这是我的问题:

 var tmpResult = JObject.Parse(File.ReadAllText(FileName)); var resultObject = tmpResult["SetNavRecords"] .Values("OfflineVerkaufspreis") .Values() .Where(n => n["Location_Code"].Value() == "MH"); 

filter工作正常,但tmpResult中的数据不完整。 我只获取“OfflineVerkaufspreis”中的数据。 我也需要根数据。

有人有想法吗?

谢谢!

通过切换到json到对象的序列化,这感觉就像一个可以变得更容易的工作。 要将json反序列化为可以使用的对象:

 RootObject obj = JsonConvert.DeserializeObject(jsonString); 

同样,你可以使用以下方法将你的对象变回json:

 string jsonString = JsonConvert.SerializeObject(RootObject); 

基于您在问题中提供的json的对象结构是这样的:

 public class OfflineVerkaufsprei { public bool Allow_Line_Discount { get; set; } public string Date { get; set; } public string Item_No { get; set; } public string Location_Code { get; set; } public double Unit_Price { get; set; } } public class SetNavRecord { public string Artikelbeschreibung { get; set; } public string Artikelbeschreibung2 { get; set; } public string Artikelnummer { get; set; } public string Artikelrabattgruppe { get; set; } public bool Gutschein { get; set; } public string MwStProduktgruppe { get; set; } public List OfflineVerkaufspreis { get; set; } } public class RootObject { public List SetNavRecords { get; set; } } 

然后,您可以通过以下方式轻松迭代您的对象:

 for each(SetNavRecord i in obj.SetNavRecords) { // do something to the record } 
 var tmpResult = JObject.Parse(File.ReadAllText(FileName)); var resultObject = tmpResult["SetNavRecords"].Values("OfflineVerkaufspreis").Values() .Where(n => n["Location_Code"].Value() == "MH"); 

此代码将导航到OfflineVerkaufspreis.Values ,然后过滤它们。 但是(我猜)您想要选择与您的Where子句匹配的位置,然后还要选择父详细信息。

您可以使用“ Select选择您真正感兴趣的所有信息。

 var resultObject = tmpResult["SetNavRecords"].Values("OfflineVerkaufspreis").Values() .Where(n => n["Location_Code"].Value() == "MH") .Select(n => new { Location = n, Context = n.Parent }).ToArray(); 

当然,您可以只选择您真正需要的信息而不是整个父母。

为了使这段代码更具可读性,我建议创建一些与JSon输入匹配的类,以便将JSon映射到这个对象图。 它将使您的Linq更容易编写,阅读和理解。

更新:在评论中建议使用: .Where(n => n["OfflineVerkaufspreis"]["Location_Code"] ...这种方法的问题是最终你不知道哪个是OfflineVerkaufspreis实际上匹配你的where子句……

我会用名称SetNavRecords和OfflineVerkaufspreis创建类。 然后我会使用命名空间System.Web.Script.Serialization.JavaScriptSerializer中的 JavaScriptSerializer对其进行反序列化。

代码就像这样 –

 JavaScriptSerializer.Deserialize(String, Type); 

然后我可以像简单的通用集合那样操作它,例如。 名单。

希望这对你有所帮助。