2012-10-28 2 views
4

JSON.Net을 사용하여 다차원 목록을 직렬화하고 올바르게 직렬화하는 데 문제가 있습니다.JSON 다차원 목록 직렬화 문제

 "children": [ { 
     "children": [ { 
      "children": [ { 
       "date_added": "12995911618983970", 
       "id": "8", 
       "name": "NestedNestedURL", 
       "type": "url", 
       "url": "http://url.com/" 
      } ], 
      "date_added": "12995911579845538", 
      "date_modified": "12995911618983970", 
      "id": "5", 
      "name": "NestedNestedFolder", 
      "type": "folder" 
     }, { 
      "date_added": "12995911609609970", 
      "id": "7", 
      "name": "NestedURL", 
      "type": "url", 
      "url": "http://url.com/" 
     } ], 
     "date_added": "12995911570603538", 
     "date_modified": "12995911609609970", 
     "id": "4", 
     "name": "NestedFolder", 
     "type": "folder" 
    }, { 
     "children": [ { 
      "date_added": "12995911631570970", 
      "id": "9", 
      "name": "NestedURL2", 
      "type": "url", 
      "url": "http://url.com/" 
     } ], 
     "date_added": "12995911589790970", 
     "date_modified": "12995911631570970", 
     "id": "6", 
     "name": "NestedFolder2", 
     "type": "folder" 
    } 

그러나, 이것은 실제로 얻는 결과에 비해 매우 다르다 : 여기

내가이 예상 결과입니다. 여기에있는 문제는 여러 개의 URL이 단일 폴더에 속할 수 있고 여러 폴더가 하나의 폴더에 속할 수 있지만이 방법을 구현할 방법이 확실하지 않습니다. 내가 그 코드에서 얻을 출력

public void Sync() 
{ 
    Browser browser = new Chrome(); 
    SortableBindingList<Bookmark> marks = browser.ReturnBookmarks(); 
    SortableBindingList<object> newmarks = new SortableBindingList<object>(); 
    int count = 0; 
    newmarks.Add(new json_top()); 
    json_top top = newmarks[0] as json_top; 

    top.roots = new json_root(); 
    List<object> roots = new List<object>(); 

    Folder bookmarks_bar = new Folder(); 
    Folder other = new Folder(); 
    List<Object> barlist = new List<Object>(); 
    List<object> otherlist = new List<object>(); 
    List<object> children = new List<object>(); 
    List<string> existingFolders = new List<string>(); 

    bookmarks_bar.date_added = ToChromeTime(marks[0].added); 
    bookmarks_bar.name = "Bookmarks bar"; 
    other.date_added = ToChromeTime(marks[0].added); 
    other.name = "Other bookmarks"; 

    bool isBookmarkBar = true; 

    Folder folder = new Folder(); 
    foreach (Bookmark mark in ordered) 
    { 
     List<string> fullpathlist = mark.fullPath.Split('\\').ToList(); 
     int count1 = 0; 
     if (currentPath != mark.fullPath) 
     { 
      folder = (createFolder(fullpathlist, fullpathlist[0], mark)); 
      folder.children.Add(setChild(fullpathlist, folder, mark, 1)); 
      count++; 
     } 
     json_URL u = new json_URL(); 
     u.date_added = ToChromeTime(mark.added); 
     u.id = id; 
     u.name = mark.title; 
     u.url = mark.url; 
     folder.children.Add(u); 
     if(isBookmarkBar) 
      barlist.Add(folder); 
     else 
     { 
      otherlist.Add(folder); 
     } 
    } 
    bookmarks_bar.children = barlist; 
    other.children = otherlist; 
    top.roots.bookmark_bar = (bookmarks_bar); 
    top.roots.other = other; 
    string json = JsonConvert.SerializeObject(newmarks, Formatting.Indented); 
    File.WriteAllText(@"c:\person.json", json); 
} 

    Folder setChild(List<string> fullPathList, Folder parent, Bookmark mark, int count) 
    { 
     if (count < fullPathList.Count) 
     { 
      Folder child = new Folder(); 
      child.date_added = ToChromeTime(mark.added); 
      child.id = id; 
      child.name = fullPathList[count]; 
      Folder LIST = setChild(fullPathList, child, mark, count + 1); 
      child.children= LIST; 
      return child; 
     }    
    } 

    public class Folder 
    { 
     public List<folderAndURL> children { get; set; } 
     public long date_added { get; set; } 
     public long date_modified 
     { 
      get { return 0; } 
     } 
     public int id { get; set; } 
     public string name { get; set; } 
     public string type 
     { 
      get { return "folder"; } 
     } 
    } 

그리고 여기에 있습니다 : : 저는 여기에 현재 사용하는 코드는

"children": [ 
     { 
     "children": { 
      "date_added": 12995893609609970, 
      "id": 0, 
      "name": "NestedURL", 
      "type": "url", 
      "url": "http://url.com/" 
     }, 
     "date_added": 12995893609609970, 
     "date_modified": 0, 
     "id": 0, 
     "name": "NestedFolder", 
     "type": "folder" 
     }, 
     { 
     "children": { 
      "date_added": 12995893618983970, 
      "id": 1, 
      "name": "NestedNestedURL", 
      "type": "url", 
      "url": "http://url.com/" 
     }, 
     "date_added": 12995893618983970, 
     "date_modified": 0, 
     "id": 1, 
     "name": "NestedFolder", 
     "type": "folder" 
     }, 
     { 
     "children": { 
      "date_added": 12995893631570970, 
      "id": 2, 
      "name": "NestedURL2", 
      "type": "url", 
      "url": "http://url.com/" 
     }, 
     "date_added": 12995893631570970, 
     "date_modified": 0, 
     "id": 2, 
     "name": "NestedFolder2", 
     "type": "folder" 
     } 

그래서, 어떻게 입력과 출력에 맞게 코드를 변경 할 수 있습니까? 내가 말했듯이, 그것은 하나의 부모 폴더에 적용되지 않는 여러 폴더에 관한 것으로 보인다.

편집 : 공백 때문에 일부 부품을 잘라 내기 때문에 here 코드의 정식 버전을 업로드했습니다.

+0

시작 구조는 무엇입니까? 여기에 다시 붙여 넣은 코드를 살펴보십시오. 그것은 불완전하고 컴파일되지 않습니다. –

+0

@JeffMercado 우주 목적으로 코드를 자르지 만, 원하는대로 붙여 넣거나 게시 할 수 있습니다. –

+0

다시보십시오. 똑같은 서명을 가진 두 개의'Sync()'메소드가 있습니다. 첫 번째는 전체가 아닙니다. 'for' 루프의 중간에서 잘린 것처럼 보입니다. 그것이 무엇을 해야하는지를 아는 것은 불가능합니다. –

답변

3

이 당신이 원하는 경우 나도 몰라 :

/// <summary> 
/// Load file from 
/// C:\Users\XXXX\AppData\Local\Google\Chrome\User Data\Default\Bookmarks 
/// </summary> 
[TestFixture] 
public class ChromeBookmarks 
{ 
    [Test] 
    public void RoundTripBookmarksTest() 
    { 
     JsonSerializer jsonSerializer = JsonSerializer.Create(
      new JsonSerializerSettings 
       { 
        MissingMemberHandling = MissingMemberHandling.Error, 
       }); 
     RootObject rootObject; 
     using (JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(Properties.Resources.Bookmarks))) //I added my bookmars as an embedded txt file for convenience 
     { 
      rootObject = jsonSerializer.Deserialize<RootObject>(jsonTextReader); 
     } 
     //Here you have the contents of the bookmarks file in rootObject if you need to do manipulations 
     StringBuilder stringBuilder = new StringBuilder(); 
     using (JsonTextWriter jsonTextWriter = new JsonTextWriter(new StringWriter(stringBuilder))) 
     { 
      jsonTextWriter.Formatting = Formatting.Indented; 
      jsonTextWriter.Indentation = 3; 
      jsonSerializer.Serialize(jsonTextWriter, rootObject); 
     } 
     var json = stringBuilder.ToString(); 
     File.WriteAllText(@"C:\person.json", json); 
    } 
} 
public class Child 
{ 
    [JsonProperty(PropertyName = "children")] 
    public List<Child> Children { get; set; } 
    [JsonProperty(PropertyName = "date_added")] 
    public string DateAdded { get; set; } 
    [JsonProperty(PropertyName = "id")] 
    public string Id { get; set; } 
    [JsonProperty(PropertyName = "name")] 
    public string Name { get; set; } 
    [JsonProperty(PropertyName = "type")] 
    public string Type { get; set; } 
    [JsonProperty(PropertyName = "url")] 
    public string Url { get; set; } 
    [JsonProperty(PropertyName = "date_modified")] 
    public string DateModified { get; set; } 
} 
public class Roots 
{ 
    [JsonProperty(PropertyName = "bookmark_bar")] 
    public Child BookmarkBar { get; set; } 
    [JsonProperty(PropertyName = "other")] 
    public Child Other { get; set; } 
    [JsonProperty(PropertyName = "synced")] 
    public Child Synced { get; set; } 
} 
public class RootObject 
{ 
    [JsonProperty(PropertyName = "checksum")] 
    public string Checksum { get; set; } 
    [JsonProperty(PropertyName = "roots")] 
    public Roots Roots { get; set; } 
    [JsonProperty(PropertyName = "version")] 
    public int Version { get; set; } 
} 

나는 클래스를 생성 this을 사용, 내용을 읽어하지 않았다 문서가 방금 내 북마크를 통과하여 일부 입력란이 누락 될 가능성이 있습니다.

3

먼저 folder.children = (setChild(fullpathlist, folder, mark, 1));을 할당하고 나중에 두 줄을 덧붙여 folder.children=(u);으로 덮어 씁니다. 폴더 객체의 재귀 호출에서 자식을 갖지 않게됩니다.

+0

잘 들어, 내 코드를 수정합니다. –