【问题标题】:Parsing and manipulating json in Scala在 Scala 中解析和操作 json
【发布时间】:2015-03-11 11:48:28
【问题描述】:

我有这个从我正在使用的 REST 服务返回的 JSON。

{
    "id": "6804",
    "signatories": [
        {
            "id": "12125",
            "fields": [
                {
                    "type": "standard",
                    "name": "fstname",
                    "value": "John"
                },
                {
                    "type": "standard",
                    "name": "sndname",
                    "value": "Doe"
                },
                {
                    "type": "standard",
                    "name": "email",
                    "value": "john.doe@somwhere.com"
                },
                {
                    "type": "standard",
                    "name": "sigco",
                    "value": "Company"
                }
            ]
        }
    ]
}

目前我正在寻找一种使用 json4s 解析它的方法,迭代“字段”数组,以便能够更改其中不同对象的属性“值”。到目前为止,我已经尝试了一些 json 库,最终得到了json4s

Json4s 允许我将 json 解析为 JObject,我可以尝试提取“字段”数组 从。

    import org.json4s._
    import org.json4s.native.JsonMethods._

    // parse to JObject
    val data = parse(json)

    // extract the fields into a map
    val fields = data \ "signatories" \ "fields"

    // parse back to JSON
    println(compact(render(fields)))

我已经成功地提取了这样的地图,并再次将其渲染回 JSON。但是我想不通的是,如何遍历这些字段并更改其中的属性“值”?

我已经阅读了 json4s 文档,但我对 Scala 和它的语法都很陌生,所以我遇到了困难。

问题变成了,我如何遍历解析的 JSON 结果,以更改属性“值”?

这是我想要实现的流程。

  1. 将 JSON 解析为可迭代对象
  2. 循环查找某些“名称”并将其值(例如 fstname)从 John 更改为其他名称。
  3. 将其解析回 JSON,以便我可以将带有更新值的新 JSON 发回。

我不知道这是否是最好的方法,我非常感谢您的意见,也许有更简单的方法。

提前致谢, 最好的问候,

斯蒂芬·康诺

【问题讨论】:

  • 有什么问题?
  • “如何遍历这些字段并更改其中的属性“值”?”。我将编辑问题,以便更好地表达问题,抱歉。
  • 您始终可以使用 \\ 运算符而无需反序列化对象。

标签: json scala json4s


【解决方案1】:

您可以将 json 转换为案例类的数组,这是最简单的事情。例如:您可以为字段设置案例类,例如

case class Field(`type`: String, name: String, value: String)

您可以将您的 json 转换为字段数组,例如 read[Array[Field]](json) 其中 json 是

 [
            {
                "type": "standard",
                "name": "fstname",
                "value": "John"
            },
            ...
        ]

这将为您提供一个字段数组。同样,您可以为整个 Json 建模。

由于现在您有一个案例类数组,因此使用案例类copy 方法迭代对象和更改值非常简单。

之后,要将对象数组转换为Json,只需使用write(objects)即可(org.json4s.native.Serialization包中有Json4s的读写功能。

Update 

要做到这一点而不将其转换为案例类,您可以使用 transformField 函数

parse(json).transformField{case JField(x, v) if x == "value" && v == JString("Company")=> JField("value1",JString("Company1"))}

【讨论】:

  • 好的,我试试。我的计划首先是使用案例类来转换我的 json。我粘贴的 json 只是我从 REST 收到的 json 的一部分,所以我无法为 50 个字段创建案例类。这就是我决定用 json4s 解析 json 的原因。我可以在不创建案例类的情况下执行此操作吗?
  • 我不确定。一段时间后我会尝试,但是,IMO,最好使用案例类的组合来构建一个更大的案例类,然后使用类似结构的大地图,Json4s 可以很容易地将 json 转换为嵌套案例类。
  • 我无法理解的是,如果我设法将签署者字段转换为案例类,则对其进行迭代并更改值。我可以以某种方式将其恢复为原始 json 吗?因为我的 json 很大,所以我只显示问题中的相关部分。但我发布到的 REST 服务需要包含更新数据和 50 多个其他字段的整个 json。
  • 是的。这应该不是问题。将具有 50 个字段的整个 json 转换为具有适当字段的案例类(字段可以简单或复杂,如其他一些较小案例类的列表)。使用案例类的复制方法随意更改字段。然后将主案例类的实例转换为json。我已经使用 json4s 为大型 json 执行此操作。它看起来很整洁。每个案例类的字段少于 5 个,主类大约有 10 个字段。
  • 不幸的是,对于一个简单的案例类,您将达到 22 个参数的限制,这使得使用生成的格式化程序更加痛苦。您需要编写自己的应用/取消应用方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-20
  • 2018-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 1970-01-01
相关资源
最近更新 更多