如何用aeson解析嵌套的JSON [英] How to parse nested JSON with aeson

查看:194
本文介绍了如何用aeson解析嵌套的JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用aeson解析以下表单的JSON

  {field:{name: ...}} 



{tag:{name:...}}



{line:{number:...}}

构造以下数据类型:

  data规则=行整数
|字段L.ByteString
|标签L.ByteString

不幸的是,我遇到了两个我没有找到解决方案的问题,即:


  1. 如何解析嵌套的JSON?查看(。:) a>,它使用查找来提取特定键的值。我很犹豫要做这样的事情,因为它似乎太依赖于aeson如何实现的具体细节。我错误地认为这是一个问题吗?

  2. 如何根据哪个键在JSON中使用正确的数据构造函数?我所有的< |>所做的努力都让我无处可寻。

我会发布我写的代码很远,但我甚至没有到达有什么值得发布的地步。

/ b>

  { - #LANGUAGE OverloadedStrings# - } 

导入Control.Applicative
导入数据。 Aeson
导入Data.Aeson.Types
将限定的Data.ByteString导入为B
将限定的Data.ByteString.Lazy导入为L
将限定的Data.Map导入为M

数据Rule =行整数
|字段L.ByteString
|标签L.ByteString
派生显示

实例FromJSON规则其中
parseJSON j = do
o < - parseJSON j - 负责JSON类型检查
案例M.toList(o :: Object)
[(field,Object o')] - >字段< $> o'。:name
[(tag,Object o')] - >标签< $> o'。:name
[(line,Object o')] - >行< $> o'。:number
_ - >失败规则:意外格式


I am trying to parse JSON of the following form using aeson

{"field":{"name":"..."}}

or

{"tag":{"name":"..."}}

or

{"line":{"number":"..."}}

to construct the following data type

data Rule = Line Integer
          | Field L.ByteString
          | Tag L.ByteString

Unfortunately, I face two problems that I've not found solutions to, namely:

  1. How do I parse nested JSON? Looking at the implementation of (.:), it uses lookup to extract a specific key's value. I'm hesitant to do something like this as it seems to be relying too much on the specifics of how aeson implements things. Am I wrong in thinking this is an issue?

  2. How do I use the correct data constructor based on which key is present in the JSON? All my efforts with <|> have led me nowhere.

I would post the code I've written thus far, but I haven't even gotten to the point where I have anything worth posting.

解决方案

How about the following?

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative
import           Data.Aeson
import           Data.Aeson.Types
import qualified Data.ByteString      as B
import qualified Data.ByteString.Lazy as L
import qualified Data.Map             as M

data Rule = Line Integer
          | Field L.ByteString
          | Tag L.ByteString
          deriving Show

instance FromJSON Rule where
  parseJSON j = do
    o <- parseJSON j -- takes care of JSON type check
    case M.toList (o :: Object) of
      [("field", Object o')] -> Field <$> o' .: "name"
      [("tag",   Object o')] -> Tag   <$> o' .: "name"
      [("line",  Object o')] -> Line  <$> o' .: "number"
      _                      -> fail "Rule: unexpected format"

这篇关于如何用aeson解析嵌套的JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆