Разбор JSON для сопоставления строки с Aeson - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь проанализировать JSON из API со структурой данных, такой как

{
  "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.locale будет ключевым именем, а значение будет просто строкой перевода JSON, как {"name": "Name", "description": ["I am a", en person"]}, потому что значение может быть произвольно сложным, и я не знаю / мне нужно преобразовать его в другую структуру данных Haskell.

Я пыталсятак много способов написать правильное parseJSON для Translation, но все равно не получается.

Буду признателен за любую помощь!

1 Ответ

0 голосов
/ 02 декабря 2018

Мы можем декодировать 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"])]))]))])

Итак, нам нужно только выполнить сопоставление для 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

Затем мы получаем Map String String, завернутый в Maybe (поскольку и декодирование, и обработка могут идти неправильно, вероятно, лучше использовать Maybe), которое отображает String s на String s:

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\"]}}")])

При этом я не уверен, что BLOB-объект JSON как значение - это то, что вам нужно, так как теперь нельзя «посмотреть» на значение и проверить, что находится внутри этого элемента.Более того, если вы хотите выполнить много поисков, Text обычно на порядок быстрее, если вы хотите проверить, совпадают ли два Text.

...