2012-04-05 12 views
8

私はドット表記を使用してアクセスできるオブジェクトに文字列を解析できるようにしたいと考えています。例えば、配列表記の代わりにmyobject.property。 myobject ['property']配列表記は正常に動作します。ここに私がこれまで持っているものがあります。ダーツを使用したJSONの解析

私はいくつかのXMLを持っている:

JSONに変換
<level1 name="level1name"> 
    <level2 type="level2Type"> 
    <entry>level2entry</entry> 
    <entry>level2entry</entry> 
    </level2> 
</level1> 

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

I以下ダートコードを有する:(所望の)出力を生成

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

答えて

12

現時点では、JSON.parseはLists(配列)、Maps、String、num、bool、およびnullを返します。 (api ref

私は、リフレクションが言語に反映されるまで、jsonで見つかったキーに基づいてオブジェクトを再構築することはできないと考えています。

しかし、JSON.parseという文字列を内部的に取得したMyJsonObjectにコンストラクタを作成し、さまざまな値を割り当てることができます。

このような何かがダーツエディタで動作します。

#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(もコンストラクタ再セスのコメントを取って)います:

+0

その言語の制限については残念です。しかし、それはすばらしい答えでした。まさに私が探していたもの。ありがとうクリス:) –

+0

MyJSONObject.fromJson(jsonString)または同様の名前のコンストラクタを使用することをお勧めします。これは、コンストラクターにとってより明白なインテントを作成します。 –

4

クリスは完全に右です。 JSONパーサーは、noSuchMethodを実装してjsonObj.propertyを許可することができる、より豊かなオブジェクト(純粋なMapの代わりにJsonMapのようなもの)を返すように変更できることを追加します。それは明らかにjsonObj['property']よりも悪くなります。

+1

このコメントに触発されて、私はそれをハックしました、そして、今githubになっています:http://github.com/chrisbu/dartwatch-JsonObject –

関連する問題