2017-02-10 2 views
0

Ich bekomme eine JSON-Daten von URL wie folgt. Aber wie Sie sehen, gibt es in Json keine Schlüsselnamen.Wie man Nicht-Schlüssel-JSON zu C# -Klassen analysiert?

Beispiel: "Flame Towers" ist ein Ortsname, aber es gibt keinen Schlüsselnamen. Ebenso ist "2017-02-10" ein Datumswert, "The Lego Batman Movie 2D" ist ein Filmnamen-Wert, aber es wird als Schlüssel deklariert und ["10:10"] ist ein Array besteht aus Filmsitzungszeiten.

Ich habe versucht, es zu C# -Klassen viel Klasse structurs für deserialize JsonConvert.DeserializeObject<ClassName>(jsonString); mit

Aber jedes Mal, es gibt ein Null-Objekt. Auch versuchte parse manuell mit JObject Klasse und es schien mir sehr verwirrt.

Also, kann jemand für echte Klassenstruktur Parsing mit JsonConvert Klasse helfen?

{ 
    { 
     "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

Haben Sie eine Kontrolle über diese hässliche „JSON“ haben - ich habe es nicht einmal JavaScript Object Notation, wie Sie nennen würde? kann sehen, es gibt keine Objektrepräsentation. – ryancdotnet

+0

Verwenden Sie 'Dictionary', siehe http://stackoverflow.com/a/1212115/224370 –

Antwort

1

Es gibt eine einfache, hacky und schnelle Art, dies zu tun. Schneiden Sie einfach die ersten und letzten {} Symbole aus der Zeichenfolge vor der Serialisierung.

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

Es ist wie Daten aus einer Sammlung von Kinos und ihren aktiven Shows sieht, wo die Top-Position „Flame Towers“, der Name des Kinos ist, die „2017.02.10“ ist das Datum und unter ist jede Show/Film und dann ihre "Anzeige" Zeit.

Mit diesem Wissen können Sie eine Datenstruktur erstellen, die diesem entspricht.

... So etwas vielleicht?

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); 
     } 
    } 

Dies ist offensichtlich nicht die eleganteste Art, das Problem zu lösen. Aber als dieser "Schlüssel-less" Json nicht einfach Deserialize ohne irgendeine Art von Hack. Erstellen einer Datenstruktur, die Ihren Bedürfnissen entspricht (mehr Handarbeit leider) wird zumindest Arbeit;)

Sie den Code oben mit dem folgenden Code verwenden:

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); 
     } 
    }     
} 

Schließlich, so wie ‚Just Shadow‘ Wie in der Antwort oben erwähnt, ist der JSON fehlerhaft und enthält zusätzliche geschweifte Klammern, die entfernt werden müssen oder das Objekt wird nicht korrekt analysiert.

0

Eine hässliche, aber recht kompakt sein, dies würde zu analysieren:

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}"); 
        } 
       } 
      } 
     } 
    } 
Verwandte Themen