Reputation: 147
I need to convert a groovy string to a map object. The string exactly is :
"\"{\\\"1\\\":[],\\\"2\\\":[],\\\"3\\\":[{\\\"name\\\":\\\"PVR_Test_Product\\\",\\\"id\\\":\\\"100048\\\"}],\\\"4\\\":[],\\\"5\\\":[]}\""
I need to fetch the value corresponding to "name". I have tried using the JsonBuilder, JsonSlurper and regexp approach for this problem. But I have not yet come to a solution.
For Simplifying things I have removed the backslashes with : replaceAll
.The reduced string is :
""{"1":[],"2":[],"3":[{"name":"PVR_Test_Product","id":"100048"}],"4":[],"5":[]}""
Looking forward to any help on this.I am using grails 2.5.1 and groovy 2.4.10.
Upvotes: 2
Views: 40438
Reputation: 109
The code below converts the JSON like string to an object or an array:
#!/usr/bin/env groovy
/**
* Get the nearest object or array end
*/
def getNearestEnd(String json, int start, String head, String tail) {
def end = start
def count = 1
while (count > 0) {
end++
def c = json.charAt(end)
if (c == head) {
count++
} else if (c == tail) {
count--
}
}
return end;
}
/**
* Parse the object
*/
def parseObject(String json) {
def map = [:]
def length = json.length()
def index = 1
def state = 'none' // none, string-value, other-value
def key = ''
while (index < length -1) {
def c = json.charAt(index)
switch(c) {
case '"':
if (state == 'none') {
def keyStart = index + 1;
def keyEnd = keyStart;
while (json.charAt(keyEnd) != '"') {
keyEnd++
}
index = keyEnd
def keyValue = json[keyStart .. keyEnd - 1]
key = keyValue
} else if (state == 'value') {
def stringStart = index + 1;
def stringEnd = stringStart;
while (json.charAt(stringEnd) != '"') {
stringEnd++
}
index = stringEnd
def stringValue = json[stringStart .. stringEnd - 1]
map.put(key, stringValue)
}
break
case '{':
def objectStart = index
def objectEnd = getNearestEnd json, index, '{', '}'
def objectValue = json[objectStart .. objectEnd]
map.put(key, parseObject(objectValue))
index = objectEnd
break
case '[':
def arrayStart = index
def arrayEnd = getNearestEnd(json, index, '[', ']')
def arrayValue = json[arrayStart .. arrayEnd]
map.put(key, parseArray(arrayValue))
index = arrayEnd
break
case ':':
state = 'value'
break
case ',':
state = 'none'
key = ''
break;
case ["\n", "\t", "\r", " "]:
break
default:
break
}
index++
}
return map
}
/**
* Parse the array
*/
def parseArray(String json) {
def list = []
def length = json.length()
def index = 1
def state = 'none' // none, string-value, other-value
while (index < length -1) {
def c = json.charAt(index)
switch(c) {
case '"':
def stringStart = index + 1;
def stringEnd = stringStart;
while (json.charAt(stringEnd) != '"') {
stringEnd++
}
def stringValue = json[stringStart .. stringEnd - 1]
list.add(stringValue)
index = stringEnd
break
case '{':
def objectStart = index
def objectEnd = getNearestEnd(json, index, '{', '}')
def objectValue = json[objectStart .. objectEnd]
list.add(parseObject(objectValue))
index = objectEnd
break
case '[':
def arrayStart = index
def arrayEnd = getNearestEnd(json, index, '[', ']')
def arrayValue = json[arrayStart .. arrayEnd]
list.add(parseArray(arrayValue))
index = arrayEnd
break
case ["\n", "\t", "\r", " "]:
break
case ',':
state = 'none'
key = ''
break;
default:
break
}
index++
}
return list
}
/**
* Parse the JSON, object or array
*/
def parseJson(String json) {
def start = json[0]
if (start == '[') {
return parseArray(json)
} else if (start == '{') {
return parseObject(json)
} else {
return null
}
}
// Test code
println parseJson('{"abdef":["Jim","Tom","Sam",["XYZ","ABC"]],{"namek":["adbc","cdef"]}}')
Upvotes: 1
Reputation: 37008
Someone is handing you down the JSON of the JSON of your data. Blindly removing the \
might end up badly. But you can just de-JSON twice.
As always in such cases: if someone is giving you data in that shape you can talk to, make sure, they have a perfectly fine reason to do such things. More often than not, this some sort of error.
def jsonOfJson = "\"{\\\"1\\\":[],\\\"2\\\":[],\\\"3\\\":[{\\\"name\\\":\\\"PVR_Test_Product\\\",\\\"id\\\":\\\"100048\\\"}],\\\"4\\\":[],\\\"5\\\":[]}\""
def slurper = new groovy.json.JsonSlurper()
def json = slurper.parseText(jsonOfJson)
println(json.inspect())
// -> '{"1":[],"2":[],"3":[{"name":"PVR_Test_Product","id":"100048"}],"4":[],"5":[]}'
def data = slurper.parseText(json)
println(data.inspect())
// -> ['1':[], '2':[], '3':[['name':'PVR_Test_Product', 'id':'100048']], '4':[], '5':[]]
assert data["3"].size()==1
Upvotes: 0
Reputation: 28564
/*
i put exactly this string into the file 1.gr
"\"{\\\"1\\\":[],\\\"2\\\":[],\\\"3\\\":[{\\\"name\\\":\\\"PVR_Test_Product\\\",\\\"id\\\":\\\"100048\\\"}],\\\"4\\\":[],\\\"5\\\":[]}\""
*/
def s= new File("./1.gr").text
println s
// output> "\"{\\\"1\\\":[],\\\"2\\\":[],\\\"3\\\":[{\\\"name\\\":\\\"PVR_Test_Product\\\",\\\"id\\\":\\\"100048\\\"}],\\\"4\\\":[],\\\"5\\\":[]}\""
s=Eval.me(s)
println s
// output> "{\"1\":[],\"2\":[],\"3\":[{\"name\":\"PVR_Test_Product\",\"id\":\"100048\"}],\"4\":[],\"5\":[]}"
s=Eval.me(s)
println s
// output> {"1":[],"2":[],"3":[{"name":"PVR_Test_Product","id":"100048"}],"4":[],"5":[]}
//now it's possible to parse json
def json = new groovy.json.JsonSlurper().parseText(s)
Upvotes: 0
Reputation: 21359
You have a json string which can be parsed with JsonSlurper
.
Here you go:
def string = """{"1":[],"2":[],"3":[{"name":"PVR_Test_Product","id":"100048"}],"4":[],"5":[]}"""
def json = new groovy.json.JsonSlurper().parseText(string)
assert json instanceof Map
You may quickly try this online Demo
Upvotes: 10