2014-02-13 5 views
3

json \\ "something"은 항상 동일한 유형의 객체 (또는 항상 최소한 동형 인 객체)를 반환 할 것으로 예상합니다. 동일한 스키마 그러나, 고려 :lift-json XPath \ 연산자는 num 일치에 따라 다른 반환 유형을 가짐

val json1 = ("people" -> List(
    ("person" -> ("name" -> "Joe")), 
    ("person" -> ("name" -> "Marilyn")))) 

val json2 = ("people" -> List(
    ("person" -> ("name" -> "Joe")))) 

val json3 = ("people" -> List[(String, String)]()) 

println((json1 \\ "name")) // JObject(List(JField(name,JString(Joe)), JField(name,JString(Marilyn)))) 
println((json2 \\ "name")) // JString(Joe) 
println((json3 \\ "name")) // JObject(List()) 

// which causes the following construction to sometimes fail 
println((json1 \\ "name").children map { case JField(_, JString(name)) => name }) 
// List(Joe, Marilyn) 
println((json2 \\ "name").children map { case JField(_, JString(name)) => name }) 
// List() !!!!! 
println((json3 \\ "name").children map { case JField(_, JString(name)) => name }) 
// List() 

를 ...은 n = 0이고 n> = 2의 경우는 지속적으로 처리되지만, N = 1 특별한 경우 너무 JValue에.

왜 이런 일이 발생합니까? 그것은 설계에 의한 것인가?

왜 하나가 같은 의미를 가지고 리프트 JSON을 \\ 연산자를 기 대해서는 안

val xml1 = <people> <person><name>Joe</name></person> <person><name>Marylin</name></person> <person><name>Erik</name></person> </people> 
val xml2 = <people> <person><name>Erik</name></person> </people> 
val xml3 = <people> </people> 

Seq(xml1, xml2, xml3).map(_ \\ "name") foreach (x => println(s"${x.getClass}\t${x.length}\t$x")) 

// OUTPUT:  
// class scala.xml.NodeSeq$$anon$1 3 <name>Joe</name><name>Marylin</name><name>Erik</name> 
// class scala.xml.NodeSeq$$anon$1 1 <name>Erik</name> 
// class scala.xml.NodeSeq$$anon$1 0 

그래서 스칼라의 XML과 비교하십시오 List

val people = List(Person(name = "Joe"), Person(name = "Mary")) 
people.map(_.name) # => returns a List 

val people = List(Person(name = "Joe")) 
people.map(_.name) # => returns a List 

val people = List() 
people.map(_.name) # => returns a List 

을 통해 매핑 비교 ? http://liftweb.net/api/26/api/#net.liftweb.json.package에서

기타 문서가 있습니다

의 XPath 같은 식 이름으로 JSON 필드를를 조회 할 수 있습니다. 일치하는 모든 필드를 반환합니다.

+0

토론 : https://groups.google.com/d/msg/liftweb/sf9ch59wEnI/XlPRq5juo8MJ –

답변

1

있음 Json4s \\은 항상 JArray을 반환합니다 (here 참조). 에서

val json1 = 
    parse(""" 
    |{ 
    | "people": [{ 
    | "name": "Joe" 
    | }, { 
    | "name": "Marilyn" 
    | }] 
    |} 
    """.stripMargin) 

val json2 = 
    parse(""" 
    |{ 
    | "people": [{ 
    | "name": "Joe" 
    | }] 
    |} 
    """.stripMargin) 


println(json1 \\ "name") 
// JArray(List(JString(Joe), JString(Marilyn))) 

println(json2 \\ "name") 
// JArray(List(JString(Joe))) 
+0

그건 좋은-I는 너무 : –

+0

리프트 3.X에 고정 것 같아요 최신 버전 3.5.0에서는 JString (Joe) 및 JObject (List ((name, JString (Joe)), (name, JString (Marilyn))))) – Pascalius