2016-07-21 70 views
1

私はDelphi XE7を使用してTwitter APIからJSON結果を解析しようとしています。私は "無効なクラスの型キャスト"エラーが表示されますが、私はJSONをオンラインベリファイアでチェックしても問題ありません。ここでJson Parse "無効なクラス型キャスト"問題。 [Delphi XE7]

は、JSONの結果である:

[ 
    { 
    "trends": 
    [ 
     { 
     "name":"#OneDirectionIsOverParty", 
     "url":"http://twitter.com/search?q=%23OneDirectionIsOverParty", 
     "promoted_content":null, 
     "query":"%23OneDirectionIsOverParty", 
     "tweet_volume":410022 
     }, 
     { 
     "name":"#TheDarkKnight", 
     "url":"http://twitter.com/search?q=%23TheDarkKnight", 
     "promoted_content":null, 
     "query":"%23TheDarkKnight", 
     "tweet_volume":null 
     }, 
     { 
     "name":"#QuintaComOClubeSdv", 
     "url":"http://twitter.com/search?q=%23QuintaComOClubeSdv", 
     "promoted_content":null, 
     "query":"%23QuintaComOClubeSdv", 
     "tweet_volume":23756 
     } 
    ], 
    "as_of":"2016-07-21T20:14:13Z", 
    "created_at":"2016-07-21T20:08:31Z", 
    "locations": 
    [ 
     { 
     "name":"Worldwide", 
     "woeid":1 
     } 
    ] 
    } 
] 

これは私の解析関数である:

procedure ParseJSON(const JSON: string); 
var 
JSONObject: TJSONObject; 
MessageText: TJSONArray; 
NodeDetails: TJSONObject; 
MsgDetail: TJSONString; 
I: Integer; 
Item: TListItem; 
begin 
JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JSON), 0) as TJSONObject; 
MessageText := JSONObject.Get('trends').JSONValue as TJSONArray; 

for I := 0 to TJSONArray(MessageText).Size - 1 do 
begin 
    Item := Form1.ListView1.Items.Add; 
    NodeDetails := MessageText.Get(I) as TJSONObject; 
    MsgDetail := NodeDetails.Get('query').JSONValue as TJSONString; 
    Item.Caption := MsgDetail.Value; 
end; 

実は、この機能は、TwitterのAPIから他のJSONの結果で動作します。この1つの結果だけでは機能しません。

+0

デバッガは、どのラインを上壊すん:

あなたのケースでは結果のコードのようなものでしょうか?まだコードを踏んだことはありますか? –

+0

Hey @JerryDodge "JSONObject:TJSONObjectとしてのTJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JSON)、0);" –

+0

私はこの特定のJSONライブラリに慣れていませんが、オブジェクトの代わりに配列として解析する必要があります。ルート要素は配列なので、私の推測です。実際、あなたのコードはこのJSONデータとまったく一致しません。 –

答えて

5
JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(JSON), 0) as TJSONObject; 

JSONのルートは、アレイ、ないオブジェクトあります。したがって、エラー。

あなたはTJSONArray代わりのTJSONObjectParseJSONValue()の戻り値をキャストする必要があり、その後、あなたは、配列の最初の要素にアクセスし、そのtrends値を読み取ることができます。配列を解析するコードはすでに用意されていますので、その方法をはっきりと知ることができます。

オブジェクトと配列のJSONの用語について明確でない場合は、JSON specをお読みください。

+2

Twitterの複数の結果を解析するのに同じコードが使用されているため、*オブジェクト*で始まり、*配列*で始まるものもあるので、 'ParseJSONValue()'の戻り値をローカルの 'TJSONValue'それをキャストする前に 'TJSONObject'か' TJSONArray'かどうかをチェックするために 'is'演算子を使います。 –

0

Davidが指摘しているように、問題は、JSONテキストがこの特定のケースでは配列であるオブジェクトであるとコードが想定していることです。

my alternative JSON libraryは、特定のJSONコンテナがオブジェクトであるか配列であるかわからない状況では、必ずしもわからない(または気にしない)JSONを処理するためのTJSONTextクラスを提供することで、 )関与するJSONがオブジェクトであるか配列であるか。

response := TJSONText.CreateFromUTF8(JSON); 

case response.ValueType of 
    jsArray : MessageText := response.AsArray[0].AsObject['trends'].AsArray; 
    jsObject : MessageText := NIL; // or as appropriate to extract "trends" from a single object response 
end; 

if Assigned(MessageText) then 
begin 
    .. etc etc 
end;