2012-04-05 65 views
8

我希望能夠將字符串解析爲可以使用點符號訪問的對象,例如, myobject.property,而不是數組符號,例如MYOBJECT [ '屬性']。數組表示法正常工作。這是迄今爲止我所擁有的。使用Dart解析JSON

我有一些XML:

<level1 name="level1name"> 
    <level2 type="level2Type"> 
    <entry>level2entry</entry> 
    <entry>level2entry</entry> 
    </level2> 
</level1> 

哪個轉換爲JSON:

{ 
    "level1": { 
    "name": "level1name", 
    "level2": { 
     "type": "level2Type", 
     "entry": [ 
     "level2entry", 
     "level2entry" 
     ] 
    } 
    } 
} 

我有以下達特代碼:

Object jsonObject = JSON.parse("""{ 
     "level1": { 
     "name": "level1name", 
     "level2": { 
      "type": "level2Type", 
      "entry": [ 
      "level2entry", 
      "level2entry" 
      ] 
     } 
     } 
    } 
"""); 

    print("my test 1 == ${jsonObject}"); 
    print("my test 2 == ${jsonObject['level1']}"); 
    print("my test 3 == ${jsonObject['level1']['name']}"); 

其產生的(期望的)輸出:

my test 1 == {level1: {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}}} 
my test 2 == {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}} 
my test 3 == level1name 

但是當我嘗試:

print("my test 1 == ${jsonObject.level1}"); 

我得到如下:

Exception: NoSuchMethodException : method not found: 'get:level1' 
Receiver: {level1: {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}}} 
Arguments: [] 
Stack Trace: 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:717 col:3 

理想情況下,我想一個對象,我可以訪問使用點符號,沒有編譯器給予警告有關對象沒有財產。我試過如下:

class MyJSONObject extends Object{ 
    Level1 _level1; 
    Level1 get level1() => _level1; 
    set level1(Level1 s) => _level1 = s; 
} 

class Level1 { 
    String _name; 
    String get name() => _name; 
    set name(String s) => _name = s; 
} 
... 
MyJSONObject jsonObject = JSON.parse("""{ 
     "level1": { 
     "name": "level1name", 
     "level2": { 
      "type": "level2Type", 
      "entry": [ 
      "level2entry", 
      "level2entry" 
      ] 
     } 
     } 
    } 
"""); 
... 
print("my test 1 == ${jsonObject.level1.name}"); 

而是給予我「level1name」的希望,我得到:

Exception: type 'LinkedHashMapImplementation<String, Dynamic>' is not a subtype of type 'MyJSONObject' of 'jsonObject'. 

什麼我錯在這裏做什麼?有什麼辦法可以做我想要的嗎?謝謝。

+0

這是一種旁白;你應該能夠從一個對象轉換爲JavaScript,並從JavaScript轉換爲JSON。 – will 2014-04-29 22:51:10

回答

12

目前,JSON.parse僅返回列表(數組),地圖,字符串,數字,布爾和空 (api ref)。

我懷疑,直到反射使其進入語言的方式,它將無法重新構建基於json中找到的鍵的對象。

但是,您可以在您的MyJsonObject中創建一個構造函數,該構造函數接受一個名爲JSON.parse的字符串,併爲其分配不同的值。

事情是這樣的作品在鏢編輯:如果你有更深層次的嵌套層次

#import("dart:json"); 
class Level2 { 
    var type; 
    var entry; 
} 

class Level1 { 
    var name; 
    var level2;   
} 

class MyJSONObject { 
    Level1 level1; 


    MyJSONObject(jsonString) { 
    Map map = JSON.parse(jsonString); 

    this.level1 = new Level1(); 
    level1.name = map['level1']['name']; 
    level1.level2 = new Level2(); 
    level1.level2.type = map['level1']['level2']['type']; 
    //etc... 

    } 
} 

main() { 
    var obj = new MyJSONObject(json); 
    print(obj.level1.level2.type); 

} 

一個不平凡的版本將需要一些循環和遞歸可能。

更新:我砍死在一起一個不平凡的版本(由下面的帖子的啓發),它up on github(也考慮Seth的意見重新構造):

+0

這種語言限制令人遺憾。但是,這是一個傑出的答案。正是我在找什麼。謝謝克里斯:) – 2012-04-05 20:09:02

+0

我可能會建議使用命名構造函數,像MyJSONObject.fromJson(jsonString)或類似的東西。這爲構造函數創建了一個更明顯的意圖。 – 2012-04-06 04:52:08

4

Chris是完全正確。我只補充說JSON解析器可以修改爲返回一個更豐富的對象(如JsonMap而不是純粹的Map),該對象可以通過執行noSuchMethod來允許jsonObj.property。這顯然會比jsonObj['property']差。

+1

受此評論的啓發,我對此有所抨擊,現在它已經發布在github上:http://github.com/chrisbu/dartwatch-JsonObject – 2012-04-12 21:28:06