漂亮的JSON multi reg到一行JSON multi reg

时间:2018-05-07 15:05:07

标签: json scala

我有一个包含许多JSON格式记录的String。我必须将每个JSON记录转换为单行JSON记录。

实施例: 输入:

{
  "field1" : "aa11",
  "field2" : "aa22",
  "structField" : {
    "sf1" : "aaa11",
    "sf2" : "aaa22"
  }
}, {
  "field1" : "bb11",
  "field2" : "bb22",
  "structField" : {
    "sf1" : "bbb11",
    "sf2" : "bbb22"
  }
}, {
  "field1" : "cc11",
  "field2" : "cc22",
  "structField" : {
    "sf1" : "ccc11",
    "sf2" : "ccc22"
  }
}

输出:

{"field1":"aa11","field2":"aa22", "structField":{"sf1" : "aaa11","sf2" : "aaa22"}},
{"field1":"bb11","field2":"bb22","structField":{"sf1" : "bbb11","sf2" : "bbb22"}}, 
{"field1" : "cc11","field2" : "cc22","structField" : {"sf1" : "ccc11","sf2" : "ccc22"}}

我正在使用Scala尝试解析String并将其拆分为"}, {"并重新格式化我的json:

myMultiJSONString.
  substring(2,myMultiJSONString.length-2).
  split("\\}, \\{").
  map(reg => "{" + reg.trim.replaceAll("\\n","") + "}")

我认为这是一种肮脏的方式。

¿有没有一些图书馆可以帮忙解决这个问题?

例如,将JSON String反序列化为“something”并稍后在单行JSON字符串中进行序列化。

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

如果输入的JSON不是太大,那么可以采用一种方法来实现这一点,而不使用"脏"技术是使用JSON解析库来解析输入数据并逐行输出,禁用"漂亮的打印"特征

输入数据的结构无关紧要,这几乎可以直接完成。

例如,使用Json4s

// since the input is not wrapped as JSON array, we need to wrap it to parse properly
val wrappedAsJsonArray = new StringBuilder("[").append(json).append("]").toString()

val parsed = parse(wrappedAsJsonArray)

implicit val formats = DefaultFormats

parsed.children.foreach(obj => {
  val oneLineJson = write(obj) + ","
  println(oneLineJson) // or write to output file
})

// the output:
{"field1":"aa11","field2":"aa22","structField":{"sf1":"aaa11","sf2":"aaa22"}},
{"field1":"bb11","field2":"bb22","structField":{"sf1":"bbb11","sf2":"bbb22"}},
{"field1":"cc11","field2":"cc22","structField":{"sf1":"ccc11","sf2":"ccc22"}},

答案 1 :(得分:0)

如果适合您的用例,最好使用适当的json api。 有大量的json apis - What JSON library to use in Scala?

我会说你可以使用circe这是一个功能性的scala json api。他们有很好的文档 - https://circe.github.io/circe/parsing.html

实施例,

import io.circe._, io.circe.parser._

object CirceAgainSerialisers {

  def main(args: Array[String]): Unit = {

    val rawFakeJson: String =
      """
        |  {
        |    "field1": "aa11",
        |    "field2": "aa22",
        |    "structField": {
        |      "sf1": "aaa11",
        |      "sf2": "aaa22"
        |    }
        |  },
        |  {
        |    "field1": "bb11",
        |    "field2": "bb22",
        |    "structField": {
        |      "sf1": "bbb11",
        |      "sf2": "bbb22"
        |    }
        |  },
        |  {
        |    "field1": "cc11",
        |    "field2": "cc22",
        |    "structField": {
        |      "sf1": "ccc11",
        |      "sf2": "ccc22"
        |    }
        |  }
      """.stripMargin

    val deserialised: Either[ParsingFailure, Json] = parse(s"[$rawFakeJson]")

    val fakeSerialise = deserialised.map(json => json.asArray.getOrElse(Vector.empty).mkString(","))

    fakeSerialise match {
      case Right(json) => println(json)
      case Left(failed) => println(failed)
    }
  }
}

你的build.sbt看起来像,

name := "serialisers-deserialisers"

version := "0.1"

scalaVersion := "2.12.2"

val circeVersion = "0.9.3"

libraryDependencies ++= Seq(
  "io.circe" %% "circe-core",
  "io.circe" %% "circe-generic",
  "io.circe" %% "circe-parser"
).map(_ % circeVersion)