2017-01-13 2 views
0

JsonTextReaderを使用して一度にトークン(.Load)を読み込むときとReadFromを使用してJSON全体を読み込むときとで、JsonPathの問題が異なる。ここでは一例です: JSON:パス= "[*]人物。" メソッド= SelectTokens(パス)JsonPath with JsonTextReader:トークンを一度に

[ 
    { 
    "person": { 
     "personid": 123456 
    } 
    }, 
    { 
    "person": { 
     "personid": 798 
    } 
    } 
] 

.ReadFromを使用している場合、それは適切な2つの要素を返します。私が.Loadを使うと、0要素が返されます。しかし、パスを ""に変更すると、.ReadFromは0要素を返し、.Loadは2要素を返します。

解決方法として、最初の "。"まで削除されるようにパスを変更することができました。すなわちpath = substring(path.index( "。")+ 1);しかし、これは適切な修正よりも多くのハックを感じます。私は、もちろん、JSONが配列であることを保証する必要もありますが、ほとんどの場合はそうです。

最後に、トークンを一度に読み込むときにJSON Pathを配列で使用する方法を学びたいと考えています。どんな勧告?あなたがリンクされているコードで何が起こっている

Full Code

Full JSON

答えて

1

それがオブジェクトに遭遇するまで、それはトークンを読み込んで、それはそれから終わりまで先読みし、このオブジェクトからJTokenをロードこのオブジェクトの。 これで、最終的には、ルート配列内の項目あたりJTokenになります。あなた各JTokenコールのためにすることができます

token.SelectTokens("person").OfType<JObject>() 

あなたはプロパティは、オブジェクトが含まれて知っている原因。

これは、解析されたJSON全体で"[*].person" JsonPathを実行することと同じです。

私はあなたの質問を正しく理解していただきたいと思います。そうでない場合、)=私に知らせてください

更新:

ご意見をもとに、私はあなたが後にしているものを理解しています。あなたはどうする可能性があり、このようなメソッドを作成することです:

public IEnumerable<JToken> GetTokensByPath(TextReader tr, string path) 
{ 
    // do our best to convert the path to a RegEx 
    var regex = new Regex(path.Replace("[*]", @"\[[0-9]*\]")); 
    using (var reader = new JsonTextReader(tr)) 
    { 
     while (reader.Read()) 
     { 
      if (regex.IsMatch(reader.Path)) 
       yield return JToken.Load(reader); 
     } 
    } 
} 

私はJSONのパス入力に基づいてパスをマッチングしていますが、私たちはさまざまなJSONパス文法の全てを試してみて、処理する必要があり、私は「現時点でmは*のみをサポートします。 この方法は、JSONパスセレクタが深い大量のファイルを持っている場合に、ゆっくりと列挙すればストリームを長く開いたままにしますが、ピークメモリ使用量ははるかに少なくなります。

こちらがお役に立てば幸いです。

+0

間違いありません。あなたの場合は、私が行ったようにパスを変更しました。私はjsonパスを上流(読者の近く)で利用できるようになるため、パスを変更する必要はありません。また、パスを修正することによって、彼らが私に[1] .personを与えた場合、私は[1]自分自身を処理する必要があります。何か案は?助けてくれてありがとう。 –

+0

最新の編集をチェックする – Stuart

関連する問題