Aeson:如何使用作为字符串化对象的元素解析对象?

时间:2015-10-17 06:44:54

标签: haskell aeson

我需要解析一个具有字符串元素的对象,其中字符串本身是一个字符串化的对象:

User

我想将其解析为{ "a" : "apples", "bar" : "{\"b\":\"bananas\"}" } 所以如果解析Just ( Foo { fooA = "apples", fooBar = Bar { barB = "bananas" } } )返回bar那么解析整个对象会返回Nothing,即结果就像是该对象的Nothing元素未被字符串化。

以下是我尝试解析bar返回testData

的尝试
Nothing

如何修改上述代码以更接近我的需要?

1 个答案:

答案 0 :(得分:3)

您可以通过以下方式更深入地了解正在发生的事情:

main = print (eitherDecode testData :: Either String Foo)

显示:Left "Error in $: expected Bar, encountered String"

在此代码中:

 parseJSON (Object o) = do bar <- (o .: "bar")
                           Foo <$> o .: "a" <*> parseJSON bar

bar的值为String ...

要完成您想要做的事情,您可以向Bar的FromJSON实例添加一个案例来捕捉这个:

instance FromJSON Bar where
  ...
  parseJSON (String text) =
    case eitherDecode (textToLBS text) of
      Left  e -> fail $ "while decoding a Bar: " ++ e
      Right b -> return b
  ...

或者您可以将此代码放在Foo的parseJSON定义中。

此处textToLBS将严格文本转换为惰性字节:

import qualified Data.Text as T
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text.Encoding as TE

textToLBS :: T.Text -> LBS.ByteString
textToLBS t = LBS.fromStrict (TE.encodeUtf8 t)

代码见:http://lpaste.net/143183