我想给jsonObject添加一个新字段,这个新字段的名称将基于另一个字段的值。为了清楚起见,这是我想实现的一个示例。
{
"values": [
{
"id": "1",
"properties": [
{
"stat": "memory",
"data": 8
},
{
"stat": "cpu",
"data": 4
}
]
},
{
"id": "2",
"properties": [
{
"stat": "status",
"data": "OK"
},
{
"stat": "cpu",
"data": 4
}
]
}
]
}
我想给每个json对象添加一个新的字段,该字段的值为“stat”作为名称。
{
"values": [
{
"id": "1",
"properties": [
{
"stat": "memory",
"data": 8,
"memory": 8
},
{
"stat": "cpu",
"data": 4,
"cpu": 4
}
]
},
{
"id": "2",
"properties": [
{
"stat": "status",
"data": 0,
"status": 0
},
{
"stat": "cpu",
"data": 4,
"cpu": 4
}
]
}
]
}
我已经尝试用JsonPath库做了以下事情,但对我来说,这是一个丑陋的解决方案,因为我将解析json三次,我做了一些手动替换。
val configuration = Configuration.builder().options(Option.DEFAULT_PATH_LEAF_TO_NULL, Option.ALWAYS_RETURN_LIST).build()
val jsonContext5 = JsonPath.using(configuration).parse(jsonStr)
val listData = jsonContext.read("$['values'][*]['properties'][*]['data']").toString
.replace("[", "").replace("]", "").split(",").toList
val listStat = jsonContext.read("$['values'][*]['properties'][*]['stat']").toString
.replace("[", "").replace("]", "")
.replace("\"", "").split(",").toList
// Replacing values of "stat" by values of "data"
jsonContext5.map("$['values'][*]['properties'][*]['stat']", new MapFunction() {
var count = - 1
override def map(currentValue: Any, configuration: Configuration): AnyRef = {
count += 1
listData(count)
}
})
// replace field stat by its value
for( count <- 0 to listStat.size - 1){
val path = s"['values'][*]['properties'][$count]"
jsonContext5.renameKey(path, "stat", s"${listStat(count)}")
}
这是得到的结果
{
"values": [
{
"id": "1",
"properties": [
{
"data": 8,
"memory": "8"
},
{
"data": 4,
"cpu": "4"
}
]
},
{
"id": "2",
"properties": [
{
"data": 0,
"memory": "0"
},
{
"data": 4,
"cpu": "4"
}
]
}
]
}
有没有更好的方法来达到这个效果?我试着用gson来做,但是它处理路径不好。
这是使用Gson的一种方法,但是我将丢失关于其他列的信息,因为我正在创建另一个json。
val jsonArray = jsonObject.get("properties").getAsJsonArray
val iter = jsonArray.iterator()
val agreedJson = new JsonArray()
while(iter.hasNext) {
val json = iter.next().getAsJsonObject
agreedJson.add(replaceCols(json))
}
def replaceCols(json: JsonObject) = {
val fieldName = "stat"
if(json.has(fieldName)) {
val columnName = json.get(fieldName).getAsString
val value: String = if (json.has("data")) json.get("data").getAsString else ""
json.addProperty(columnName, value)
}
json
}
5条答案
按热度按时间ebdffaop1#
像这样的怎么样?
nkhmeac62#
使用Gson,您应该做的是创建一个表示初始JSON对象的基类。然后,将JSON对象加载到内存中,可以逐个加载,也可以全部加载,然后对每个对象进行必要的更改以包含您的更改。然后,如果在上一步中没有将这些更改Map到新类,则将其Map到新类,并将它们序列化到文件或其他存储中。
6kkfgxo03#
这是一个类型安全的纯FP
circe
实现,使用circe-optics
:xurqigkl4#
Gene McCulley的前一个答案给出了一个使用Java和类net.minidev.json的解决方案,这个答案使用类Gson,用Scala编写。
xkftehaa5#
您的任务是在JSON文件的每个属性下为每条记录添加一个新字段,使当前的stat值成为字段名,数据值成为新字段值。如果尝试用Java来做,代码会相当长。
建议你使用SPL,一个开源的Java包来完成它。编码将非常容易,你只需要一行:
| | A级|
| - -|- -|
| 一个|=json(json(file(“数据. json”).read()).值.运行(属性=属性.(([[“统计”,“数据”]|统计]|[~.数组()|数据]).record())))|
SPL提供了Java调用的JDBC驱动程序,只需将上面的SPL脚本存储为addfield.splx,在Java应用程序中调用存储过程时调用它即可: