2017-02-10 11 views
0

私は次のようにURLからJsonデータを取得します。しかし、あなたが見るように、Jsonにはキー名はありません。キー以外のJSONをC#クラスに解析する方法は?

たとえば、「Flame Towers」は地名の値ですが、キー名はありません。同様に、 "2017-02-10"は日付値、 "The Lego Batman Movie 2D"は映画名の価値ですが、キーと宣言され、 "10:10"はフィルムセッション時間で構成される配列です。

私は

JsonConvert.DeserializeObject<ClassName>(jsonString);を使用してC#クラスにデシリアライズのための多くのクラスstructursを試みたが、すべての時間は、それがヌルオブジェクトを返します。また、JObjectクラスで手動で解析してみたところ、私は非常に混乱していたようでした。

だから、JsonConvertクラスで真のクラス構造解析を手助けできますか?

{ 
    { 
     "Flame Towers": { 
      "2017-02-10": { 
       "The Lego Batman Movie 2D": [ 
        "10:10" 
       ], 
       "Qatil 2D": [ 
        "10:30" 
       ], 
       "Fifty Shades Darker 2D": [ 
        "10:30", 
        "11:40", 
        "12:50", 
        "14:00", 
        "15:10", 
        "16:20", 
        "17:30", 
        "18:40", 
        "19:50", 
        "21:00", 
        "22:10", 
        "23:20", 
        "00:30", 
        "01:40" 
       ], 
       "John Wick: Chapter Two 2D": [ 
        "11:00", 
        "12:10", 
        "13:20", 
        "14:30", 
        "15:40", 
        "16:50", 
        "18:00", 
        "20:20", 
        "21:30", 
        "22:40", 
        "23:50", 
        "01:00", 
        "02:10" 
       ], 
       "The Lego Batman Movie 3D": [ 
        "11:00", 
        "12:10", 
        "13:00", 
        "14:10", 
        "15:00", 
        "17:00", 
        "19:00" 
       ], 
       "Ballerina 3D": [ 
        "16:10" 
       ], 
       "Rings 2D": [ 
        "17:55" 
       ], 
       "Ağanatiq 2D": [ 
        "19:55" 
       ], 
       "Resident Evil: The Final Chapter 3D": [ 
        "21:40", 
        "21:00", 
        "23:50", 
        "01:10" 
       ], 
       "The Great Wall 3D": [ 
        "23:10" 
       ] 
      } 
     }, 
     "Metro Park": { 
      "2017-02-10": { 
       "John Wick: Chapter Two 2D": [ 
        "10:30", 
        "12:50", 
        "15:10", 
        "17:30", 
        "19:50", 
        "22:10", 
        "00:30" 
       ], 
       "Ağanatiq 2D": [ 
        "10:00", 
        "11:50", 
        "13:40", 
        "15:30", 
        "17:20", 
        "19:10", 
        "21:00", 
        "23:00", 
        "00:50" 
       ], 
       "The Lego Batman Movie 2D": [ 
        "10:30" 
       ], 
       "Fifty Shades Darker 2D": [ 
        "11:00", 
        "13:20", 
        "15:40", 
        "18:00", 
        "20:20", 
        "02:00" 
       ], 
       "Hoqqa 2D": [ 
        "11:10", 
        "12:50", 
        "14:30", 
        "16:10", 
        "17:50", 
        "19:30", 
        "21:10", 
        "22:50", 
        "00:30", 
        "02:10" 
       ], 
       "Naxox 2D": [ 
        "11:20", 
        "13:10", 
        "15:00", 
        "16:50", 
        "18:40", 
        "20:30", 
        "22:20", 
        "00:10" 
       ], 
       "The Lego Batman Movie 3D": [ 
        "12:30", 
        "14:30", 
        "16:30", 
        "18:30" 
       ], 
       "Ballerina 3D": [ 
        "20:30" 
       ], 
       "Resident Evil: The Final Chapter 3D": [ 
        "22:40", 
        "00:50" 
       ], 
       "The Great Wall 3D": [ 
        "22:20", 
        "02:30" 
       ], 
       "Притяжение 3D": [ 
        "00:20" 
       ] 
      } 
     } 
    } 
} 
+0

あなたはこの醜い「JSON」以上の任意のコントロールを持っていますか - 私もあなたのように、javascriptオブジェクトの表記、それを呼び出すことはありません?見ることができます、オブジェクト表現はありません。 – ryancdotnet

+0

'Dictionary'を使用してください(http://stackoverflow.com/a/1212115/224370を参照)。 –

答えて

1

これを行う簡単で、ハッキーで迅速な方法があります。シリアライズする前に、最初の文字列と最後の文字列を{}のように切り取ってください。

if (jsonString.StartsWith("{{") && jsonString.EndsWith("}}")) 
    jsonString = jsonString.Substring(2, jsonString.Length - 4); 
JsonConvert.DeserializeObject<ClassName>(jsonString); 
0

それは映画館と一番上の項目「炎の塔」は映画館の名前です、それらの活性のショーのコレクションからのデータのように見え、「2017年2月10日」の日付と下です各ショー/ムービーとその「表示」時間。

これを知ることで、これに一致するデータ構造を作成できます。

...これはおそらく何か?

public class Movie : IEnumerable<TimeSpan> 
    { 

     public Movie(string name, IReadOnlyList<TimeSpan> runTimes) 
     { 
      this.Name = name; 
      this.RunTimes = runTimes; 
     } 

     public string Name { get; } 

     public IReadOnlyList<TimeSpan> RunTimes { get; } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return GetEnumerator(); 
     } 

     public IEnumerator<TimeSpan> GetEnumerator() 
     { 
      return RunTimes.GetEnumerator(); 
     } 

     public override string ToString() 
     { 
      return "[Movie] " + Name; 
     } 

     public static Movie Parse(JProperty data) 
     { 
      var name = data.Name; 
      var runTimes = new List<TimeSpan>(); 

      foreach (var child in data.Values()) 
      { 
       runTimes.Add(TimeSpan.Parse(child.Value<string>())); 
      } 

      return new Movie(name, runTimes); 
     } 
    } 


    public class MovieCollectionDate : IEnumerable<Movie> 
    { 

     public MovieCollectionDate(DateTime date, IReadOnlyList<Movie> movies) 
     { 
      this.Date = date; 
      this.Movies = movies; 
     } 

     public DateTime Date { get; } 

     public IReadOnlyList<Movie> Movies { get; } 


     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return GetEnumerator(); 
     } 

     public IEnumerator<Movie> GetEnumerator() 
     { 
      return this.Movies.GetEnumerator(); 
     } 

     public override string ToString() 
     { 
      return "[Date] " + Date + " - " + Movies.Count + " show(s)"; 
     } 

     public static MovieCollectionDate Parse(JProperty data) 
     { 
      var date = DateTime.Parse(data.Name); 
      var movies = new List<Movie>(); 

      foreach (var upperChild in data.Children<JObject>()) 
      { 
       foreach (var child in upperChild.Children()) 
       { 
        movies.Add(Movie.Parse(child as JProperty)); 
       } 
      } 

      return new MovieCollectionDate(date, movies); 
     } 
    } 

    public class MovieTheatre : IEnumerable<MovieCollectionDate> 
    { 

     public MovieTheatre(string name, IReadOnlyList<MovieCollectionDate> dateAndMovies) 
     { 
      this.Name = name; 
      this.DateAndMovies = dateAndMovies; 
     } 

     public string Name { get; } 
     public IReadOnlyList<MovieCollectionDate> DateAndMovies { get; } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return GetEnumerator(); 
     } 

     public IEnumerator<MovieCollectionDate> GetEnumerator() 
     { 
      return this.DateAndMovies.GetEnumerator(); 
     } 

     public override string ToString() 
     { 
      return "[Theatre] " + Name + " - " + DateAndMovies.Count + " open day(s)"; 
     } 


     public static MovieTheatre Parse(JProperty data) 
     { 
      var name = data.Name; 
      var movieCollectionDates = new List<MovieCollectionDate>(); 
      foreach (var upperChild in data.Children<JObject>()) 
      { 
       foreach (var child in upperChild.Children()) 
       { 
        movieCollectionDates.Add(MovieCollectionDate.Parse(child as JProperty)); 
       } 
      } 

      return new MovieTheatre(name, movieCollectionDates); 
     } 
    } 

    public class MovieTheatreCollection : IEnumerable<MovieTheatre> 
    { 

     public MovieTheatreCollection(IReadOnlyList<MovieTheatre> movieTheatres) 
     { 
      this.MovieTheatres = movieTheatres; 
     } 

     public IReadOnlyList<MovieTheatre> MovieTheatres { get; } 

     IEnumerator IEnumerable.GetEnumerator() 
     { 
      return GetEnumerator(); 
     } 

     public IEnumerator<MovieTheatre> GetEnumerator() 
     { 
      return this.MovieTheatres.GetEnumerator(); 
     } 

     public override string ToString() 
     { 
      return "MovieTheatreCollection: Containing " + MovieTheatres.Count + " movie theatre(s)"; 
     } 

     public static MovieTheatreCollection Parse(JObject data) 
     { 
      var theatres = new List<MovieTheatre>(); 
      foreach (var child in data.Children().Cast<JProperty>()) 
      { 
       theatres.Add(MovieTheatre.Parse(child)); 
      } 
      return new MovieTheatreCollection(theatres); 
     } 
    } 

これは明らかに問題を解決する最もエレガントな方法ではありません。しかし、この "キーレス"のjsonが何らかのハックなしに正しくデシリアライズを行えないのを見ると、あなたのニーズにマッチしたデータ構造(残念ながら多くの手作業)意志少なくとも仕事の作成、次のコードで上記のコードを使用することができます

):同じように、最後に

JObject obj = JObject.Parse(... the json string you had above ...) 

MovieTheatreCollection movieTheatres = MovieTheatreCollection.Parse(obj); 

foreach (var movieTheatre in movieTheatres) 
{ 
    Console.WriteLine(movieTheatre); 
    foreach (var openDay in movieTheatre) 
    { 
     Console.WriteLine(" " + openDay); 
     foreach (var movie in openDay) 
     { 
      Console.WriteLine("  " + movie); 
      foreach (var runtime in movie) Console.WriteLine("  - " + runtime); 
     } 
    }     
} 

をただ影 "上記の答えで述べたように、jsonは不正な形式であり、削除する必要のある余分な中括弧が含まれているか、オブジェクトは適切に解析されません。

0

これを解析する醜いが、合理的にコンパクトな方法は、次のようになります。

static void Main(string[] args) 
    {     
     var jo = JObject.Parse(File.ReadAllText("data.json").Trim('{').Trim('}')); 
     foreach (var place in jo) 
     { 
      Console.WriteLine($"Place: {place.Key}"); 
      foreach (var dateOrMovie in place.Value.Children<JProperty>()) 
      { 
       Console.WriteLine($"\tDate: {dateOrMovie.Name}"); 
       var movies = dateOrMovie.Children<JObject>().First().Children<JProperty>(); 
       foreach (var movie in movies) 
       { 
        Console.WriteLine($"\t\t{movie.Name}"); 
        foreach (JValue time in movie.Children<JArray>().First()) 
        { 
         Console.WriteLine($"\t\t\t{time.Value}"); 
        } 
       } 
      } 
     } 
    } 
関連する問題