同じスキーマを持つデータに対する同じクエリに対して、json \\ "something"
常に同じタイプのオブジェクト (または少なくとも常に同形のもの) を返すことが期待されますが、次の点を考慮してください。
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
.
なぜこうなった?それは設計によるものですか?
上のマッピングと比較してください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
Scala の XML との比較
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
\\
では、lift-jsonオペレーターが同じセマンティクスを持つことを期待してはならないのはなぜでしょうか?
http://liftweb.net/api/26/api/#net.liftweb.json.packageのドキュメントには次のものがあります。
JSON フィールドを名前でクエリするための XPath に似た式。一致するすべてのフィールドを返します。