簡體   English   中英

如何檢查解析后的Aeson價值?

[英]How to inspect parsed Aeson Value?

如何瀏覽大Aeson Values 我知道應該有一個我感興趣的字符串嵌套在結構中的某個位置。 我如何找到它?

到目前為止,我只知道如何查詢構造函數,發現它是一個數組。 我怎么能比這更深入?

> take 20 $ show bt
"Array (fromList [Obj"

lens軟件包具有有用的功能,可用於檢查類似JSON Value的樹狀結構。 還有lens-aeson包,帶有額外的JSON特定功能。

import Data.Text
import Data.Aeson
import Data.Aeson.Lens (_Value,_String) -- this is from lens-aeson
import Data.Foldable (toList)

import Control.Lens (Fold,folding,universeOf,toListOf,paraOf,preview)

我們可以從定義鏡頭Fold開始,該鏡頭Fold提取給定JSON Value的直接子Values

vchildren :: Fold Value Value
vchildren = folding $ \v -> case v of
    Object o -> toList o
    Array a -> toList a
    _ -> []

foldinglens創建的功能,而Fold是返回列表的功能。 在我們的例子中,是Value的列表。

我們可以將vchildrenControl.Lens.PlateduniverseOf函數結合使用,以獲取提取Value 所有傳遞后代(包括其自身)的函數:

allValues :: Value -> [Value]
allValues = universeOf vchildren

並且此函數提取Value中包含的所有文本。 它使用_String從棱鏡Data.Aeson.Lens (一個Prism是有點像可以被傳遞了“具體化”模式):

allTexts :: Value -> [Text]
allTexts = toListOf (folding allValues . _String)

Control.Lens.Plated還具有諸如paraOf類的有趣功能,可用於構建“ paramorphims”。 亞同態是從葉子開始的樹狀結構的“受控破壞”,並向上構建結果。 例如這個功能

vpara :: (Value -> [r] -> r) -> Value -> r
vpara = paraOf vchildren

將另一個函數作為其第一個參數,該函數接收“當前節點”以及下面節點的中間結果,並構建當前節點的中間結果。

vpara將開始從葉子中使用JSON值(這些節點的中間結果列表只是[] )並向上進行。

vpara一種可能用法是獲取JSON中路徑的列表,該列表以匹配某些條件的文本結尾,如下所示:

type Path = [Value]

pathsThatEndInText :: (Text -> Bool) -> Value -> [Path]
pathsThatEndInText pred = vpara func
  where
    func :: Value -> [[Path]] -> [Path]
    func v@(String txt) _ | pred txt = [[v]]
    func v l@(_:_) = Prelude.map (v:) (Prelude.concat l)
    func _ _ = []

為了獲得由pathsThatEndInText返回的路徑之一的某種可讀性描述:

import qualified Data.HashMap.Strict as HM
import qualified Data.Vector as V

describePath :: Path -> [String]
describePath (v:vs) = Prelude.zipWith step (v:vs) vs
  where
    step (Object o) next = (unpack . Prelude.head . HM.keys . HM.filter (==next)) o
    step (Array a) next = (show . maybe (error "not found") id) (V.elemIndex next a)
    step _ _ = error "should not happen"

最后,這是一個示例JSON值,用於在ghci中測試上述功能:

exampleJSON :: Value
exampleJSON = maybe Null id (preview _Value str)
  where
    str = "[{ \"k1\" : \"aaa\" },{ \"k2\" : \"ccc\" }, { \"k3\" : \"ddd\" }]"

這就是要點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM