JArray。如果索引可以改变,如何处理Jarray?

时间:2015-03-16 16:39:43

标签: c# json json.net

我需要进程JSON文件,该文件可能包含JSON数组中不同数量的项目。目前我正在使用这样的代码:

var obj = JArray.Parse(File.ReadAllText(url));
dfd = (from a in obj
       where
           a["PriceItems"][0]["CityFromID"].Value<string>() == cityfromcode &&
           a["PriceItems"][0]["CityToID"].Value<string>() == citytocode &&
           a["PriceItems"][0]["AirlineCode"].Value<string>() == airlinecode
       select new PricesViewModel.DepartureFlightsData
       {
           DepartureCity = a["PriceItems"][0]["CityFromName"].Value<string>(),
           DepartureAirport = a["PriceItems"][0]["AirportFromCode"].Value<string>(),
           DepartureDate = depDate,
           DepartureTime = a["PriceItems"][0]["DepartureTime"].Value<string>(),
           DepartureAirline = a["PriceItems"][0]["AirlineCode"].Value<string>(),
           DepartureFlight = a["PriceItems"][0]["FlightNumber"].Value<string>(),
           DepartureFlightId = a["PriceItems"][0]["FlightID"].Value<string>(),
           Price = a["PriceItems"][0]["Price"].Value<int>(),
           Currency = a["PriceItems"][0]["Currency"].Value<string>()
       }).FirstOrDefault();

但是这段代码只对特定索引的项目有效,我应该如何更改此代码才能处理某些特定位置的项目,与[0]不同?

JSON可能会改变:

[
  {
    "PriceItems": [
      {
        "FlightID": "567",
        "FlightNumber": "001",
        "CityFromID": "1",
        "CityFromCode": "MOW",
        "CityToID": "539",
        "CityToCode": "",
        "AirportFromCode": "DME",
        "AirportFromName": null,
        "AirportToCode": "VRN",
        "AirportToName": null,
        "DepartureDate": "20150318",
        "DepartureTime": "10:00",
        "ArrivalDate": "20150318",
        "ArrivalTime": "12:00",
        "Price": 300,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "aerobus A-310",
        "AirlineName": "Сан Экспресс",
        "AirlineCode": "00",
        "PackageID": "232",
        "CityFromName": "Москва",
        "CityToName": "ВАРНА"
      },
      {
        "FlightID": "568",
        "FlightNumber": "002",
        "CityFromID": "539",
        "CityFromCode": null,
        "CityToID": "1",
        "CityToCode": null,
        "AirportFromCode": "VRN",
        "AirportFromName": null,
        "AirportToCode": "DME",
        "AirportToName": null,
        "DepartureDate": "20150319",
        "DepartureTime": "12:00",
        "ArrivalDate": "20150319",
        "ArrivalTime": "14:00",
        "Price": 300,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "aerobus A-310",
        "AirlineName": "Сан Экспресс",
        "AirlineCode": "00",
        "PackageID": "232",
        "CityFromName": "ВАРНА",
        "CityToName": "Москва"
      }
    ],
    "VariantItems": [
      {
        "FlightID": "567",
        "FlightBackID": "568"
      }
    ],
    "Error": null
  },
  {
    "PriceItems": [
      {
        "FlightID": "569",
        "FlightNumber": "546",
        "CityFromID": "1",
        "CityFromCode": "MOW",
        "CityToID": "559",
        "CityToCode": "",
        "AirportFromCode": "DME",
        "AirportFromName": null,
        "AirportToCode": "SFA",
        "AirportToName": null,
        "DepartureDate": "20150318",
        "DepartureTime": "08:00",
        "ArrivalDate": "20150318",
        "ArrivalTime": "10:00",
        "Price": 200,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "BRITISH  AIRWAYS",
        "AirlineCode": "BA",
        "PackageID": "232",
        "CityFromName": "Москва",
        "CityToName": "СОФИЯ"
      },
      {
        "FlightID": "571",
        "FlightNumber": "547",
        "CityFromID": "559",
        "CityFromCode": null,
        "CityToID": "1",
        "CityToCode": null,
        "AirportFromCode": "SFA",
        "AirportFromName": null,
        "AirportToCode": "DME",
        "AirportToName": null,
        "DepartureDate": "20150319",
        "DepartureTime": "18:00",
        "ArrivalDate": "20150319",
        "ArrivalTime": "20:00",
        "Price": 185,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "BRITISH  AIRWAYS",
        "AirlineCode": "BA",
        "PackageID": "232",
        "CityFromName": "СОФИЯ",
        "CityToName": "Москва"
      }
    ],
    "VariantItems": [
      {
        "FlightID": "569",
        "FlightBackID": "571"
      }
    ],
    "Error": null
  }
]

到那一个:

[
  {
    "PriceItems": [
      {
        "FlightID": "565",
        "FlightNumber": "731",
        "CityFromID": "1",
        "CityFromCode": "MOW",
        "CityToID": "19",
        "CityToCode": "BCN",
        "AirportFromCode": "DME",
        "AirportFromName": null,
        "AirportToCode": "BCN",
        "AirportToName": null,
        "DepartureDate": "20150318",
        "DepartureTime": "17:00",
        "ArrivalDate": "20150318",
        "ArrivalTime": "21:00",
        "Price": 350,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "TRANSAERO",
        "AirlineCode": "UN",
        "PackageID": "232",
        "CityFromName": "Москва",
        "CityToName": "Барселона"
      },
      {
        "FlightID": "563",
        "FlightNumber": "2639",
        "CityFromID": "1",
        "CityFromCode": "MOW",
        "CityToID": "19",
        "CityToCode": "BCN",
        "AirportFromCode": "SVO",
        "AirportFromName": null,
        "AirportToCode": "BCN",
        "AirportToName": null,
        "DepartureDate": "20150318",
        "DepartureTime": "11:50",
        "ArrivalDate": "20150318",
        "ArrivalTime": "19:15",
        "Price": 350,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "Aeroflot-Russian International AirLines",
        "AirlineCode": "SU",
        "PackageID": "232",
        "CityFromName": "Москва",
        "CityToName": "Барселона"
      },
      {
        "FlightID": "566",
        "FlightNumber": "732",
        "CityFromID": "19",
        "CityFromCode": null,
        "CityToID": "1",
        "CityToCode": null,
        "AirportFromCode": "BCN",
        "AirportFromName": null,
        "AirportToCode": "DME",
        "AirportToName": null,
        "DepartureDate": "20150319",
        "DepartureTime": "07:00",
        "ArrivalDate": "20150319",
        "ArrivalTime": "11:00",
        "Price": 350,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "TRANSAERO",
        "AirlineCode": "UN",
        "PackageID": "232",
        "CityFromName": "Барселона",
        "CityToName": "Москва"
      },
      {
        "FlightID": "564",
        "FlightNumber": "2640",
        "CityFromID": "19",
        "CityFromCode": null,
        "CityToID": "1",
        "CityToCode": null,
        "AirportFromCode": "BCN",
        "AirportFromName": null,
        "AirportToCode": "SVO",
        "AirportToName": null,
        "DepartureDate": "20150319",
        "DepartureTime": "11:50",
        "ArrivalDate": "20150319",
        "ArrivalTime": "14:50",
        "Price": 350,
        "Currency": "€",
        "AirServiceID": "89",
        "AirCraft": "Boeing",
        "AirlineName": "Aeroflot-Russian International AirLines",
        "AirlineCode": "SU",
        "PackageID": "232",
        "CityFromName": "Барселона",
        "CityToName": "Москва"
      }
    ],
    "VariantItems": [
      {
        "FlightID": "563",
        "FlightBackID": "566"
      },
      {
        "FlightID": "565",
        "FlightBackID": "566"
      },
      {
        "FlightID": "563",
        "FlightBackID": "564"
      },
      {
        "FlightID": "565",
        "FlightBackID": "564"
      }
    ],
    "Error": null
  }
]

2 个答案:

答案 0 :(得分:1)

据我了解,您首先要收到&#34; PriceItems&#34;对象。 您可以使用SelectMany() LINQ extension method。该方法将完全符合您的要求:

var obj = JArray.Parse(File.ReadAllText(url));
dfd = obj.SelectMany(x => x["PriceItems"])
   .Select(a => new PricesViewModel.DepartureFlightsData {
       DepartureCity = a["CityFromName"].Value<string>(),
       DepartureAirport = a["AirportFromCode"].Value<string>(),
       DepartureDate = depDate,
       DepartureTime = a["DepartureTime"].Value<string>(),
       DepartureAirline = a["AirlineCode"].Value<string>(),
       DepartureFlight = a["FlightNumber"].Value<string>(),
       DepartureFlightId = a["FlightID"].Value<string>(),
       Price = a["Price"].Value<int>(),
       Currency = a["Currency"].Value<string>()
   }).FirstOrDefault();

答案 1 :(得分:1)

这是一个更简单的选择。

public class VarientItemsPlaceHolder
{
     public string FlightID;
     public string FlightBackID;
}

public class OuterJsonObject
{
      public List<PricesViewModel.DepartureFlightsData> PriceItems;
      public List<VarientItemsPlaceHolder> VarientItems;
      public strint Error;
}

// deserialize the whole thing first
List<OuterJsonObject> everything = JsonConvert.DeserializeObject<OuterJsonObject>(File.ReadAllText(url));

// flatten the Lists of PricesViewModel.DepartureFlightsData into one master List<PricesViewModel.DepartureFlightsData>   
List<PricesViewModel.DepartureFlightsData> allFlights = everything.SelectMany(x => x.PricedItems).ToList();


// filter the master list using cityfromcode, citytocode, airlinecode
List<PricesViewModel.DepartureFlightsData> filteredFlights = allFlights.Where(x => x.CityFromID == cityfromcode && x.CityToID == citytocode && x.AirlineCode == airlinecode).ToList();

请注意,您不必像我一样彻底解决这个问题。代码可以通过组合这些LINQ查询来压缩,我只是选择逐步进行,因为它使数据处理更加清晰。

正如其他人指出的那样,关键是使用SelectMany方法聚合包含该列表的每个对象的所有PricedItems。我个人更喜欢使用静态类型。在转换为您的模型类型之前,您正在使用JArray作为中介,这可以继续,您可能已经在模型中已经定义了我在这里定义的类型,所以不要使用我的类定义,我只是把它们放在那里,以明确它是如何工作的。 json等同于我的OuterJsonObject类型,在我反序列化后,我只是LINQ查询,或者两个远离了你想要的过滤列表。