2010-10-01 17 views
11

Có cách nào để sử dụng lớp JObject của thư viện lift-json để hoạt động như một Bản đồ không?Tôi có thể sử dụng thư viện Scala lift-json để phân tích cú pháp JSON thành Bản đồ không?

Ví dụ:

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> 

kỷ lục tôi lại có thể ngờ ("foo") để trở về "thanh"

tôi nhận thấy một hàm giá trị và nó in ra một bản đồ nhưng đối tượng thực tế là một 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")

Có những ví dụ với thư viện lift-json giải nén một lớp trường hợp nhưng trong trường hợp này, tôi không biết schema json trước.

+0

Đây là một câu trả lời liên quan cho phân tích bản đồ như một tham số trong một trường hợp lớp http://stackoverflow.com/questions/5051290/deserializing-case-classes-with-mapstring-any-properties-with-lift-json/6310493#6310493 –

Trả lời

12

Nếu bạn nhìn vào thực hiện, bạn sẽ thấy

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 
} 

Vì vậy, điều này sẽ làm việc:

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

Bạn cũng có thể thử

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

Cảm ơn, công trình đầu tiên hoạt động, tùy chọn thứ hai của việc áp dụng () trả về lỗi. Tôi đã kết thúc bằng cách sử dụng trình phân tích cú pháp java dựng sẵn của scala. scala.util.parsing.json.JSON.parseFull (bản ghi) sẽ trả về một số (Bản đồ) hoặc một số (Danh sách) –

7

JValue.Values ​​là một loại phụ thuộc đường dẫn. Có nghĩa là nếu bạn giữ trên một JString nó sẽ là một String, hoặc nếu bạn có một JArray nó sẽ là một List [Any]. Nếu bạn chắc chắn rằng JSON bạn phân tích cú pháp là một đối tượng JSON, bạn có thể truyền nó thành một loại thích hợp.

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

Một con đường loại phụ thuộc cho JObject là một bản đồ [String, Bất kỳ], như sau:

scala> record.values("foo")          
res0: Any = bar 

Chỉ cần tò mò, không phải là nó một chút vấn đề nếu bạn không biết hình dạng của dữ liệu bạn sẽ phân tích cú pháp?

Lưu ý, nếu dữ liệu của bạn chứa (tên, mô tả, tuổi) và độ tuổi là tùy chọn bạn có thể đọc mà JSON thành:

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

Tôi có một json có một mảng các trường khác nhau. Ví dụ: tài liệu đầu tiên có thể có (tên, mô tả, tuổi) nhưng tài liệu thứ hai chỉ có thể có (tên, tuổi) được chỉ định. Nếu tôi sử dụng đối tượng Map của scala, tôi chỉ có thể gọi document.getOrElse ("foo", "") –