2013-06-24 2 views
11

임의의 키가있는 중첩 JSON 객체가 여러 개 있습니다. AB, C이 미리 알 수Aeson - Haskell의 임의 JSON 키

{ 
    "A": { 
     "B": { 
      "C": "hello" 

     } 
    } 

} 

. 이 세 사람은 각각 형제가있는 이 될 수도 있습니다.

Aeson이 사용자 정의 유형으로 이것을 구문 분석하는 방법이 있는지 궁금합니다. 몇 가지 우아한 방법입니다. 내가 한 일은 Aeson Object에로드하는 것입니다.

이런 종류의 JSON 개체에 대해 FromJSON을 어떻게 구현 하시겠습니까?

감사합니다.

편집는 :

{ 
    "USA": { 
     "California": { 
      "San Francisco": "Some text" 
     } 
    }, 
    "Canada": { 
     ... 
    } 
} 

이 ... CountryDatabase 곳으로 컴파일해야

type City   = Map String String 
type Country   = Map String City 
type CountryDatabase = Map String Country 
+1

이 JSON을 어떻게 해석 하시겠습니까? 항상 3 개의 중첩 된 키가 있고 그 다음에 문자열이 있습니까? –

+0

파싱 할 사용자 정의 유형의 예를 들려 줄 수 있습니까? 나는 그것이 그 질문을 분명히 할 것이라고 생각한다. –

+0

데이터 구조의보다 구체적인 예를 사용하여 질문이 업데이트되었습니다. –

답변

18

당신은 Map String vFromJSON 인스턴스를 다시 사용할 수 있습니다. 다음과 같은 뭔가 :

{-# LANGUAGE OverloadedStrings #-} 

import Data.Functor 
import Data.Monoid 
import Data.Aeson 
import Data.Map (Map) 
import qualified Data.ByteString.Lazy as LBS 
import System.Environment 

newtype City = City (Map String String) 
    deriving Show 

instance FromJSON City where 
    parseJSON val = City <$> parseJSON val 

newtype Country = Country (Map String City) 
    deriving Show 

instance FromJSON Country where 
    parseJSON val = Country <$> parseJSON val 

newtype DB = DB (Map String Country) 
    deriving Show 

instance FromJSON DB where 
    parseJSON val = DB <$> parseJSON val 

main :: IO() 
main = do 
    file <- head <$> getArgs 
    str <- LBS.readFile file 
    print (decode str :: Maybe DB) 

출력 :

[email protected]:/tmp/shum$ cat in.js 
{ 
    "A": { 
     "A1": { 
      "A11": "1111", 
      "A22": "2222" 
     } 
    }, 
    "B": { 
    } 
} 
[email protected]:/tmp/shum$ runhaskell test.hs in.js 
Just (DB (fromList [("A",Country (fromList [("A1",City (fromList [("A11","1111"),("A22","2222")]))])),("B",Country (fromList []))])) 
[email protected]:/tmp/shum$ 

PS : 당신은 내가 단지 명확성을 위해 그들을 사용 newtype의없이 그것을 할 수 있습니다.

+0

이 답변은 매우 유용합니다! 문자열이 아닌 값을 무시하도록 수정 될 수 있습니까? 예를 들어''1111 ''을'1111'로 바꾸면 구문 분석이 실패합니다. – davidchambers

+0

ToJSON 인스턴스는 어떻게 생겼을까요? – AdHominem