我有一個JSON文檔從支持系統API中撤回。通過我的代碼,我想動態地提取預配置的字段,假設我的程序調用API時JSON可能會包含更多或更少的期望字段。使用Groovy動態分析JSON
我有一些可行的代碼,雖然它看起來非常複雜和低效。
這裏是JSON的作品,我很感興趣的一個片段:
{
"rows": [
{
"assignee_id": 1,
"created": "2017-01-25T14:13:19Z",
"custom_fields": [],
"fields": [],
"group_id": 2468,
"priority": "Low",
"requester_id": 2,
"status": "Open",
"subject": "Support request",
"ticket": {
"description": "Ticket descritpion",
"id": 1000,
"last_comment": {
"author_id": 2,
"body": "Arbitrary text",
"created_at": "2017-02-09T14:21:38Z",
"public": false
},
"priority": "low",
"status": "open",
"subject": "Support request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:21:38Z",
"updated_by_type": "Agent"
},
{
"assignee_id": 1,
"created": "2017-02-09T14:00:18Z",
"custom_fields": [],
"fields": [],
"group_id": 3579,
"priority": "Normal",
"requester_id": 15,
"status": "Open",
"subject": "Change request",
"ticket": {
"description": "I want to change this...",
"id": 1001,
"last_comment": {
"author_id": 20,
"body": "I want to change the CSS on my website",
"created_at": "2017-02-09T14:12:12Z",
"public": true
},
"priority": "normal",
"status": "open",
"subject": "Change request",
"type": "incident",
"url": "Arbitrary URL"
},
"updated": "2017-02-09T14:12:12Z",
"updated_by_type": "Agent"
}
]
}
我有一個ArrayList叫我建立wantedFields從配置來定義我想從拉出哪些信息該JSON:
["id","subject","requester_id","status","priority","updated","url"]
的複雜性在於數據的API中複製的,我只希望在「行」一旦拔出的數據,與該數據的偏好適用。我的做法如下。這感覺就像我在重複代碼,但我無法真正看到如何更高效地完成這項工作。 JSON保存爲「viewAsJson」。
def ArrayList<Map<String,Object>> assignConfiguredFields(viewAsJson, wantedFields) {
//Pull out configured fields from JSON and store as Map to write as CSV later
ArrayList<Map<String,Object>> listOfDataToWrite = new ArrayList<Map<String,Object>>()
ArrayList<String> rowKeyList = new ArrayList<String>()
def validationRow = viewAsJson.rows.get(0)
//Compare one row object to config first
validationRow.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
rowKeyList.add(k)
}
}
ArrayList<String> ticketKeyList = new ArrayList<String>()
def validationTicket = viewAsJson.rows.ticket.get(0)
//Compare one ticket object to config first
validationTicket.each { k, v ->
if (wantedFields.contains(k)) {
wantedFields.remove(k)
ticketKeyList.add(k)
}
}
def rows = viewAsJson.rows
def tickets = viewAsJson.rows.ticket
//Pull matching ticket objects from JSON and store in Map
ArrayList<Map<String,Object>> tickList= new ArrayList<>()
ArrayList<Map<String,Object>> rowList= new ArrayList<>()
rows.each { row ->
Map<String,Object> rowMap = new HashMap<>()
row.each { k, v ->
if(rowKeyList.contains(k))
rowMap.put(k,v)
}
rowList.add(rowMap)
}
tickets.each { ticket ->
Map<String,Object> ticketMap = new HashMap<>()
ticket.each { k, v ->
if(ticketKeyList.contains(k))
ticketMap.put(k, v)
}
tickList.add(ticketMap)
}
for (int i = 0; i < rowList.size(); i++) {
HashMap<String,Object> dataMap = new HashMap<>()
dataMap.putAll(rowList.get(i))
dataMap.putAll(tickList.get(i))
listOfDataToWrite.add(dataMap)
}
println listOfDataToWrite
return listOfDataToWrite
}
我知道應該有一些驗證,如果wantedFields ArrayList仍然填充。我多次迭代這個代碼,這次我忘了重新添加。
因此給出了Json以及按鍵[[「id」,「subject」,「requester_id」,「status」,「priority」,「updated」,「url」]'的鍵列表,你期望輸出是? –
從示例JSON '[「id」:1000,「subject」:「支持請求」,「requester_id」:2,「status」:「open」,「priority」:「low」,「updated」:「 2017-02-09T14:21:38Z「,」url「:」任意網址「] 我已經意識到了代碼中的一個錯誤 - 雖然我現在正在解決這個問題。 – Donglecow
好的,我現在已經修復了代碼。我期待它遍歷JSON並從「rows」數組中的每個項目中提取配置的數據。 EG: '[[「id」:1000,「subject」:「支持請求」,「requester_id」:2,「status」:「打開」,「優先級」:「低」,「更新」: 「2017-02-09T14:21:38 Z」,「url」:「任意URL」],[「id」:1001,「subject」:「變更請求」,「requester_id」:15,「status」: 「開放」,「優先」:「正常」,「更新」:「2017-02-09T14:12:12Z」,「網址」:「任意網址」]] – Donglecow