1

我在json_answer (Text.JSON 包)中使用了答案,并且我有一个通用的 json Haskell 数据类型。为某些数据定义自定义的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

我使用Data.Aeson了图书馆,它解决了我的问题。

decodeinData.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 回答
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 对象只有一个“类别”字段,那么它就是一个类别,“地址”也是如此。要真正完成这项工作,您需要在 case 和 readJSON 中添加另一个子句以指示“解析”错误。

然后解析你的例子,你会这样做:

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

由于这个例子,它神奇地起作用:

JSON a => JSON [a]

可能有更好的方法可以做到这一点,但这对我有用,而且看起来很简单。

于 2012-12-29T05:22:28.643 回答