2013-10-01 4 views
2

В моем приложении я хочу показать папку и ее содержащие закладки. Я стараюсь, чтобы добиться чего-то вроде этого:Parse json string to object with linq

  • папку Википедии
    • URL
    • URL б
    • URL ...
  • папку StackOverflow
    • URL
    • url b

Поэтому я должен разобрать следующий JSON строку:

{ 
     "checksum": "7d7205349eb64a4894aafc5ce074c0c0", 
     "roots": { 
      "bookmark_bar": { 
      "children": [ { 
       "children": [ { 
        "date_added": "13021579661026871", 
        "id": "28", 
        "name": "design patterns - Do you allow the Web Tier to access the DAL directly? - Stack Overflow", 
        "type": "url", 
        "url": "http://stackoverflow.com/questions/796656/do-you-allow-the-web-tier-to-access-the-dal-directly" 
       }, { 
        "date_added": "13021665700468056", 
        "id": "31", 
        "name": "VS 2010 Error when creating or opening projects - Stack Overflow", 
        "type": "url", 
        "url": "http://stackoverflow.com/questions/8403853/vs-2010-error-when-creating-or-opening-projects" 
       } ], 
       "date_added": "13021579680308871", 
       "date_modified": "13024947520078515", 
       "id": "29", 
       "name": "StackOverflow", 
       "type": "folder" 
      }, { 
       "children": [ { 
        "date_added": "13022096980978880", 
        "id": "45", 
        "name": "Dependency injection - Wikipedia, the free encyclopedia", 
        "type": "url", 
        "url": "http://en.wikipedia.org/wiki/Dependency_injection" 
       }, { 
        "date_added": "13024941326636844", 
        "id": "124", 
        "name": "Strategy pattern - Wikipedia, the free encyclopedia", 
        "type": "url", 
        "url": "http://en.wikipedia.org/wiki/Strategy_pattern" 
       } ], 
       "date_added": "13023315356559470", 
       "date_modified": "13024946156966435", 
       "id": "72", 
       "name": "Wiki", 
       "type": "folder" 
      }, { 
       "children": [ { 
        "date_added": "13023667785042757", 
        "id": "85", 
        "name": "Anemic Domain Model Illustrated | Frequent incoherent cogitation", 
        "type": "url", 
        "url": "http://vitamic.wordpress.com/2007/01/04/anemic-domain-model-illustrated/" 
       } ], 
       "date_added": "13023667668403520", 
       "date_modified": "13023668043391377", 
       "id": "82", 
       "name": "#Read", 
       "type": "folder" 
      }, { 
       "date_added": "13025102943539897", 
       "id": "130", 
       "name": "Modern UI for WPF - Home", 
       "type": "url", 
       "url": "http://mui.codeplex.com/wikipage?title=screenshots&referringTitle=Home" 
      } ], 
      "date_added": "13020681767991841", 
      "date_modified": "13025102947408897", 
      "id": "1", 
      "name": "Lesezeichenleiste", 
      "type": "folder" 
      } 
     }, 
     "version": 1 
    } 

Я попытался функции GroupBy, как это без успеха:

var items = jObject.Descendants() 
        .Where(x => x.Type == JTokenType.Object && 
           x.Value<string>("type") != null) 
        .GroupBy(x => x.Value<string>("type")); 

    foreach (var item in items) 
    { 
     Console.WriteLine(item.Key.ToString()); 
     foreach (var children in item) 
     { 
      Console.WriteLine(" " + children.Value<string>("name")); 
     } 
    } 

Я также пытался сделать применить функция Join, но здесь отсутствует свойство join. Может кто-нибудь указать мне в правильном направлении, пожалуйста?

ответ

6

Я бы проанализировал, что json использует конкретные классы.

var root = JsonConvert.DeserializeObject<RootObj>(json); 
Print(root.roots.bookmark_bar,""); 

void Print(Node n,string padding) 
{ 
    Console.WriteLine(padding + "+" + n.name); 
    foreach(var url in n.children.Where(c => c.type == "url")) 
    { 
     Console.WriteLine(padding + "\t-" + url.name); 
    } 
    foreach (var folder in n.children.Where(c => c.type == "folder")) 
    { 
     Print(folder, padding + "\t"); 
    } 
} 

public class Node 
{ 
    public string date_added { get; set; } 
    public string date_modified { get; set; } 
    public string id { get; set; } 
    public string name { get; set; } 
    public string type { get; set; } 
    public string url { get; set; } 
    public List<Node> children { get; set; } 
} 

public class Roots 
{ 
    public Node bookmark_bar { get; set; } 
} 

public class RootObj 
{ 
    public string checksum { get; set; } 
    public Roots roots { get; set; } 
    public int version { get; set; } 
} 

Приведенный выше код достаточно, чтобы разобрать ваш JSON, но если вы хотите * date_modified * и * DATE_ADDED * поля как DateTime, вы можете реализовать класс JsonConverter

var root = JsonConvert.DeserializeObject<RootObj>(json, new DateTimeConverter()); 

class DateTimeConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(DateTime); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return new DateTime(1970,1,1).Add(TimeSpan.FromTicks(long.Parse((string)reader.Value))); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Тогда ваш Узел класс будет

public class Node 
{ 
    public DateTime date_added { get; set; } 
    public DateTime date_modified { get; set; } 
    public string id { get; set; } 
    public string name { get; set; } 
    public string type { get; set; } 
    public string url { get; set; } 
    public List<Node> children { get; set; } 
} 
+0

Это прекрасно работает ТНХ для усилий! – MUG4N