8

myobject['property'] などの配列表記の代わりに、ドット表記 (myobject.property など) を使用してアクセスできるオブジェクトに文字列を解析できるようにしたいと考えています。配列表記は正常に機能します。これが私がこれまでに持っているものです。

私はいくつかの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"
      ]
    }
  }
}

次の Dart コードがあります。

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'.

ここで何が間違っていますか?私がしようとしていることをする方法はありますか?ありがとう。

4

2 に答える 2

12

現時点では、JSON.parseはリスト(配列)、マップ、文字列、num、bool、およびnull(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);

}

自明でないバージョンでは、より深いネストされたレベルがある場合、いくつかのループと可能な再帰が必要になります。

更新:私は重要なバージョン(以下の投稿に触発された)を一緒にハックしました、それはgithubにあります(コンストラクターに関するSethのコメントも取ります):

于 2012-04-05T17:40:37.463 に答える
4

クリスは完全に正しいです。JSON パーサーを変更して、を実装することで可能になる少しリッチなオブジェクト ( JsonMappure ではなくのようなもの) を返すことができることだけを追加します。それは明らかに よりもパフォーマンスが悪いでしょう。MapjsonObj.propertynoSuchMethodjsonObj['property']

于 2012-04-05T20:52:02.877 に答える