我使用 Mulesoft 4、Dataweave 2.3。 我想展平 JSON 对象。 JSON 中的每个键都应该位于新记录对象的键中。当 JSON 具有嵌套对象/数组时,键将用“.”连接。 因此准备将其作为记录插入到数据库表中,而不会丢失原始 JSON 的键名。 这是我传入的 JSON 消息:
{
"supplierId": "123456",
"targets": {
"test": "JustAtest"
},
"assets": [
{
"id": "1229782",
"serialNumber": "120007324",
"name": "Machine A",
"gpsPostition": {
"longitude": 12.234,
"Latitude": 45.12
},
"used": [
{
"startTime": "2023-12-12T08:08:00.345Z",
"KWH": 234
},
{
"startTime": "2023-12-13T08:08:00.372Z",
"KWH": 240
}
]
},
{
"id": "1229781",
"serialNumber": "120007323",
"name": "Machine B1",
"gpsPostition": {
"longitude": 18.229,
"Latitude": 123.487
},
"used": [
{
"startTime": "2023-12-14T10:15:00.231Z",
"KWH": "220"
},
{
"startTime": "2023-12-15T10:15:00.117Z",
"KWH": "154"
}
]
}
]
}
这应该是结果:
var ExpectedResult = [
{"supplierId." : "123456"},
{"targets.test." : "JustAtest"},
{"assets.id." : "1229782"},
{"assets.serialNumber." : "120007324"},
{"assets.name.": "Machine A"},
{"assets.gpsPostion.longitude.": 12.234},
{"assets.gpsPostion.latitude.": 45.12},
{"assets.used.startTime.": "2023-12-12T08:08:00.345Z"},
{"assets.used.KWH.": 234},
{"assets.used.startTime.": "2023-12-13T08:08:00.372Z"},
{"assets.used.KWH.": 240},
{"assets.id." : "1229781"},
{"assets.serialNumber." : "120007323"},
{"assets.name.": "Machine B1"},
{"assets.gpsPostion.longitude.": 18.229},
{"assets.gpsPostion.latitude.": 123.487},
{"assets.used.startTime.": "2023-12-14T10:15:00.231Z"},
{"assets.used.KWH.": 220},
{"assets.used.startTime.": "2023-12-15T10:15:00.117Z"},
{"assets.used.KWH.": 154}
]
这是我尝试过的:
fun testMe(mesg1: Any, prefix, newRecords: Any) = do {
fun createDbsRecord(mesg: Any, prefix) = do {
var pre = if(prefix == null) "" else prefix ++ "."
---
mesg match {
case mesg is Object -> mesg mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key)))
case [x ~ xs] -> mesg map ($ mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key))))
//case mesg is Array -> mesg map ($ mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ key)))
else -> (newRecords << {(pre): (mesg)})
}
}
---
createDbsRecord(mesg1, null)
}
output application/json
---
//mesg is the incoming JSON message
testMe(mesg, null, [])
这是我收到的错误:
''' 无法将 Array ([{"supplierId.": "123456"}]) 强制转换为 Object
120| case mesg 是 Object -> mesg mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ '''
我在调试中注意到 newRecords 数组似乎没有填充新对象(记录)。而且 mesg1 数组也没有被破坏。对象不会被移除。
采用这个问题的优秀方法,你可以获得预期的结果。我必须添加对数组的支持并删除它们的索引(假设所有数字键都是索引)。默认情况下,我没有在按键末尾添加点。您可以取消注释一行来获取它。
%dw 2.0
import * from dw::util::Tree
import isNumeric from dw::core::Strings
fun collectLeaves(data) =
if ((data is Object) == false)
data
else
data mapObject ((value, key, index) -> value match {
case value is Object -> collectLeaves(value)
case value is Array -> value reduce ((item, accumulator = {}) -> accumulator ++ collectLeaves(item))
else ->
(key): value
})
fun objToProperties(obj) =
(obj pluck ((value, key, index) ->
(key): value
))
var aggregatedKeys = payload mapLeafValues (value, path) -> {
(path.selector
filter (!isNumeric($)) // removed array indexes
joinBy "."
// ++ "." // uncomment if you want a dot at the end of the key
):
value
}
output application/json
---
collectLeaves(aggregatedKeys)
输出:
{
"supplierId": "123456",
"targets.test": "JustAtest",
"assets.id": "1229782",
"assets.serialNumber": "120007324",
"assets.name": "Machine A",
"assets.gpsPostition.longitude": 12.234,
"assets.gpsPostition.Latitude": 45.12,
"assets.used.startTime": "2023-12-12T08:08:00.345Z",
"assets.used.KWH": 234,
"assets.used.startTime": "2023-12-13T08:08:00.372Z",
"assets.used.KWH": 240,
"assets.id": "1229781",
"assets.serialNumber": "120007323",
"assets.name": "Machine B1",
"assets.gpsPostition.longitude": 18.229,
"assets.gpsPostition.Latitude": 123.487,
"assets.used.startTime": "2023-12-14T10:15:00.231Z",
"assets.used.KWH": "220",
"assets.used.startTime": "2023-12-15T10:15:00.117Z",
"assets.used.KWH": "154"
}