【问题标题】:Parsing JSON to Map String String with Aeson使用 Aeson 解析 JSON 以映射字符串字符串
【发布时间】:2018-12-02 11:01:33
【问题描述】:

我正在尝试从 API 解析 JSON,其数据结构类似于

{
  "en": {
    "translation": {
      "name": "Name",
      "description": ["I am a", "en person"]
    }
  },
  "jp": {
    "translation": {
      "name": "JP Name",
      "description": ["I am a", "jp person"]
    }
  }
}

所以我只想将它们解析为newtype Translations = Map String String 之类的东西。语言环境将是键名,值将只是 JSON 转换的字符串,例如 {"name": "Name", "description": ["I am a", en person"]},因为该值可能是任意复杂的,我不关心/需要将其转换为其他 Haskell 数据结构。

我尝试了很多方法来为Translation 写一个合适的parseJSON,但仍然无法成功。

任何帮助将不胜感激!

【问题讨论】:

    标签: json parsing haskell aeson


    【解决方案1】:

    我们可以解码ByteString

    Prelude Data.Aeson Bs Hm Mp Tx> decode text :: Maybe Object
    Just (fromList [("jp",Object (fromList [("translation",Object (fromList [("name",String "JP Name"),("description",Array [String "I am a",String "jp person"])]))])),("en",Object (fromList [("translation",Object (fromList [("name",String "Name"),("description",Array [String "I am a",String "en person"])]))]))])
    

    那么我们只需要对包裹在`Object构造函数中的HashMap Text Object进行映射:

    import Data.Aeson
    import qualified Data.ByteString.Lazy.Char8 as Bs
    import qualified Data.HashMap.Lazy as Hm
    import qualified Data.Map as Mp
    import qualified Data.Text as Tx
    
    process :: Value -> Maybe (Mp.Map String String)
    process (Object m) = Just ((Mp.fromList . map f) (Hm.toList m))
        where f (x, y) = (Tx.unpack x, Bs.unpack (encode y))
    process _ = Nothing
    

    然后我们获得一个包裹在Maybe 中的Map String String(因为解码和处理都可能出错,使用Maybe 可能更好),它将Strings 映射到String年代:

    Prelude Data.Aeson Bs Hm Mp Tx> decode text >>= process
    Just (fromList [("en","{\"translation\":{\"name\":\"Name\",\"description\":[\"I am a\",\"en person\"]}}"),("jp","{\"translation\":{\"name\":\"JP Name\",\"description\":[\"I am a\",\"jp person\"]}}")])
    

    话虽如此,我不确定 JSON blob 作为值是否是您想要的,因为现在无法“查看”该值并检查该元素内部的内容。此外,如果您想要进行大量查找,当您想要检查两个 Texts 是否相同时,Text 通常会快一个数量级。

    【讨论】:

    • 非常感谢威廉。这很有帮助。对我来说,关键的一点是使用AE.encode 来序列化 Aeson 中的 Object :) 不敢相信我在这里被困了几个小时。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2015-02-15
    • 1970-01-01
    相关资源
    最近更新 更多