Scala & json4s - анализиране на JSON с полета, които започват с цифров знак

Имам дълбоко вложени анализатори на JSON (използвайки json4s.jackson), които се опитвам да опростя с помощта на класове case.

Проблемът ми е... някои от полетата започват с числа, но scala не може да има име на аргумент, което започва с цифров знак.

Пример:

import org.json4s.jackson.JsonMethods._
import org.json4s._

implicit val formats = DefaultFormats

val jsonStr = """{"5gLog":{"i":99}}"""      // <--- note the field "5gLog"
val jval = parse(jsonStr)

case class Raw5gLog(i: Int)
val raw5gLog = (jval \ "5gLog").extract[Raw5gLog]

Това работи. Но това, което трябва да направя, тъй като тези полета са вложени дълбоко в JSON... е нещо подобно...

val jsonStr = """{"xgLog":{"i":99}}"""
val jval = parse(jsonStr)

case class RawRecord(xgLog: Raw5gLog)
val rawRecord = jval.extract[RawRecord]

Това би работило... ако полетата са именувани като xgLog, но полетата всъщност са именувани като 5gLog както по-горе, и не мога да дам име на аргумент на клас като 5gLog...

case class RawRecord(5gLog: Raw5gLog)
// error: Invalid literal number

Мислех си за нещо подобно

parse(jsonStr.replace("\"5g", "\"fiveg"))

Но има реални данни, извън имената на полетата, в JSON, които могат да бъдат засегнати.

Най-доброто решение, което мога да измисля, е да добавя допълнителни методи за прилагане към засегнатите класове на случай...

case class RawRecord(fivegLog: Raw5gLog)

object RawRecord {
  def apply(jval: JValue): RawRecord =
    RawRecord( (jval \ "5gLog").extract[Raw5gLog] )
}

val rawRecord = RawRecord(jval)

Но имам чувството, че всеки път, когато направя някакво структурно различно решение като това за краен случай, това винаги е началото на кода ми, който се превръща в бъркотия. Бих могъл да дам на всеки клас case нов метод за прилагане и да го използвам за всичко, но изглежда като много допълнителен код за малка част от данните.

Има ли по-добър начин?


person kmh    schedule 06.05.2021    source източник


Отговори (1)


Scala може да използва всеки низ като име на променлива, но може да се наложи да го поставите в кавички с обратни точки:

case class RawRecord(`5gLog`: Raw5gLog)

Също така трябва да направите това, ако имате поле, наречено type или друга запазена дума. Ето как - може да бъде име на функция, например.

person Tim    schedule 06.05.2021