我从url获取Json数据如下。但是如你所见,Json中没有关键名称。
例如,"火焰塔"是地名名称值,但没有任何键名。同样," 2017-02-10"是日期值,"乐高蝙蝠侠电影2D"是电影名称值,但它被声明为关键,[" 10:10"]是一个数组包含电影会话时间。
我尝试了许多类结构,使用JsonConvert.DeserializeObject<ClassName>(jsonString);
但每次返回一个null对象。还尝试用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 :(得分:1)
这样做有一种简单,苛刻和快速的方法。在序列化之前,只需从字符串中剪切第一个和最后一个{
}
个符号。
if (jsonString.StartsWith("{{") && jsonString.EndsWith("}}"))
jsonString = jsonString.Substring(2, jsonString.Length - 4);
JsonConvert.DeserializeObject<ClassName>(jsonString);
答案 1 :(得分:0)
它看起来像一组电影院及其活动节目的数据,其中顶部项目“火焰塔”是电影院的名称,“2017-02-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);
}
}
}
最后,就像上面答案中提到的“Just Shadow”一样,json格式错误,包含需要删除的额外大括号或对象无法正确解析。
答案 2 :(得分: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}");
}
}
}
}
}