1

json_answer(Text.JSONパッケージ)の回答を使用し、一般的なjsonHaskellデータ型を使用しました。特定のデータに対してカスタムHaskellデータ型を定義することは問題ありませんが、解析したいデータが不確かな場合は、

たとえば、一部のAPIから応答Aを受け取った場合、今回のフィールドは「カテゴリ」です。

[JSObject (JSONObject {fromJSObject = [("category",JSString (JSONString {fromJSString = "photo"}))]})]

そして次回、「アドレス」:

[JSObject (JSONObject {fromJSObject = [("address",JSString (JSONString {fromJSString = "http://www.example.com"}))]})]

または他のいくつかの不確実なフィールド、および一般的なjsonタイプがネストされている可能性があります。

jsonデータ型からどのように抽出できますか?

ご協力いただきありがとうございます。

4

2 に答える 2

2

のドキュメントを見るだけでText.JSON、次のようなものが役立つ可能性があります。

import Text.JSON

data Foo = Category String
         | Address String
         deriving (Show)

toJSO = JSObject . toJSObject

instance JSON Foo where
    showJSON (Category s) = toJSO [("category", showJSON s)]
    showJSON (Address s)  = toJSO [("address",  showJSON s)]
    readJSON (JSObject obj) = case o of
      [("category", JSString s)] -> Ok $ Category $ fromJSString s
      [("address",  JSString s)] -> Ok $ Address  $ fromJSString s
      where
        o = fromJSObject obj

基本的に、これは次のように言います。JSONオブジェクトに「category」フィールドしかない場合、それはCategoryであり、「address」についても同じです。これを実際に機能させるには、ケースに別の句を追加し、「解析」エラーを示すためのreadJSONを追加します。

次に、例を解析するには、次のようにします。

decode "some-JSON-here" :: Result [Foo]

このインスタンスのために魔法のように機能します:

JSON a => JSON [a]

これを行うにはおそらくもっと良い方法がありますが、これは私にとってはうまくいき、かなり簡単に思えます。

于 2012-12-29T05:22:28.643 に答える
2

Data.Aesonライブラリを使用して、質問を解決しました。

decodeinは結果Data.Aesonを生成できMaybe Valueます。そして、パターンマッチングを使用して、次のMaybe Valueように結果から値を抽出しました。

json2Array :: Maybe Value -> Array
json2Array (Just (Array anArray)) = anArray

arrayValue2Object :: Value -> Object
arrayValue2Object (Object anObject) = anObject

また、Data.Aesonでは、Objectコンストラクターはの同義語であるHashMap Text Valueため、Data.HashMap.Lazy/Strictを使用して必要な値を抽出できます。

この方法は良くないかもしれませんが、それは本当に私を助けました。

于 2012-12-31T22:33:20.550 に答える