2010-10-01 73 views
11

有沒有辦法使用lift-json庫的JObject類來像一個Map一樣?我可以使用Scala lift-json庫將JSON解析爲Map嗎?

例如:

val json = """ 
{ "_id" : { "$oid" : "4ca63596ae65a71dd376938e"} , "foo" : "bar" , "size" : 5} 
""" 

val record = JsonParser.parse(json) 
record: net.liftweb.json.JsonAST.JValue = JObject(List(JField(_id,JObject(List(JField($oid,JString(4ca63596ae65a71dd376938e))))), JField(foo,JString(bar)), JField(size,JInt(5)))) 

</code> 

我本來期望的記錄(「富」)返回「巴」

我注意到一個值函數,它打印出地圖,但實際的對象是JValue.this.Values?

scala> record.values res43: record.Values = Map((_id,Map($oid -> 4ca63596ae65a71dd376938e)), (foo,bar), (size,5))

scala> record.values("foo") :12: error: record.values of type record.Values does not take parameters record.values("foo")

有與升降JSON庫提取案例類的例子,但在這種情況下,我不知道提前JSON模式。

+0

這是一個case類解析地圖作爲參數相關答案http://stackoverflow.com/questions/5051290/deserializing-case-classes-with-mapstring-any-properties-with-lift-json/6310493#6310493 – 2011-06-10 18:57:33

回答

12

如果你看看實現,你會看到

case class JObject(obj: List[JField]) extends JValue { 
    type Values = Map[String, Any] 
    def values = Map() ++ obj.map(_.values.asInstanceOf[(String, Any)]) // FIXME compiler fails if cast is removed 
} 

所以這應該工作:

record.values.asInstanceOf[Map[String, Any]]("foo") 

您也可以嘗試

record.values.apply("foo") 
+0

謝謝,第一個作品,第二個選擇使用apply( )返回一個錯誤。我結束了使用scala的內置java解析器。 scala.util.parsing.json.JSON.parseFull(記錄)將返回一些(地圖)或一些(列表) – 2010-10-01 21:14:03

7

JValue.Values是路徑依賴型。這意味着如果你持有一個JString,它將是一個字符串,或者如果你有一個JArray,它將是一個List [Any]。如果您確定您分析的JSON是JSON對象,則可以將其轉換爲適當的類型。

val record = JsonParser.parse(json).asInstanceOf[JObject] 

的路徑依賴型的JObject是Map [字符串,任何],即:

的好奇心
scala> record.values("foo")          
res0: Any = bar 

只是,是不是有點問題,如果你不知道的形狀你要解析的數據?

請注意,如果您的數據包含(名稱,描述,歲)和年齡是可選的,你可以閱讀JSON到:

case class Person(name: String, description: String, age: Option[Int]) 
+0

我有一個json,它有一個不同的字段數組。例如。第一份文件可能有(姓名,描述,年齡),但第二份文件可能只有(姓名,年齡)指定。如果我使用scala的Map對象,我可以調用document.getOrElse(「foo」,「」) – 2010-10-01 21:25:59

相關問題