简体   繁体   English

如何解析Haskell中JSON的不确定数据?

[英]How to parse uncertain data from JSON in Haskell?

I used the answer in json_answer (Text.JSON package) and I've got a generic json Haskell data type. 我在json_answer (Text.JSON包)中使用了答案,并且我有一个通用的json Haskell数据类型。 It's ok to define a custom Haskell data type for certain data, but if the data I want to parse is uncertain, 可以为某些数据定义自定义Haskell数据类型,但如果我要解析的数据不确定,

For example, if I got a response A from some APIs, the field is "category" this time: 例如,如果我从某些API获得响应A,则此时该字段为“类别”:

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

And next time, "address": 下一次,“地址”:

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

or some other uncertain fields, and the generic json type may be nested. 或其他一些不确定的字段,通用的json类型可以嵌套。

how can I extract it from the json data type? 如何从json数据类型中提取它?

Thanks for your help. 谢谢你的帮助。

Just looking at the documentation for Text.JSON , something like this might work for you: 只需查看Text.JSON的文档,这样的内容可能对您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

Basically this says: if the JSON object has just a "category" field then it's a Category, and same for "address". 基本上这说:如果JSON对象只有一个“类别”字段,那么它就是一个类别,对于“地址”也是如此。 To really make this work you'd add another clause to the case and the readJSON for indicating a "parse" error. 要真正完成这项工作,您需要在案例中添加另一个子句,并使用readJSON来指示“解析”错误。

Then to parse your example, you'd do: 然后解析你的例子,你会做:

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

which magically works because of this instance: 由于这个例子,它神奇地起作用:

JSON a => JSON [a]

There are probably better ways of doing this, but this worked for me and seems pretty straightforward. 可能有更好的方法来做到这一点,但这对我有用,看起来非常简单。

I used Data.Aeson library and it solved my question. 我使用了Data.Aeson库,它解决了我的问题。

decode in Data.Aeson can produce a Maybe Value result. decodeData.Aeson可生产Maybe Value的结果。 And I used pattern matching to extract the values from the Maybe Value result like follow: 我使用模式匹配从Maybe Value结果中提取值,如下所示:

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

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

And in Data.Aeson, Object constructor is a synonym of HashMap Text Value so I can use the Data.HashMap.Lazy/Strict to extract the values I need. 在Data.Aeson中, Object构造函数是HashMap Text Value的同义词,因此我可以使用Data.HashMap.Lazy / Strict来提取我需要的值。

This method may not good, but it realy helped me. 这种方法可能不太好,但它确实帮助了我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM