Find value in nested map (parsed from JSON)

Hallo,

i converted a JSON to a very complex nested map.
I only need one value out of this map. It is the field “system”.
In my example the value is “DEV130PHYSTEST”.
Can anyone help me to find this value in this map with Scala?

Some(Map(type -> SUCCESS, msg -> Container D4SContRules successfully called., result -> Map(execution-results -> Map(results -> List(Map(key -> , value -> 1.0), Map(key -> output, value -> List(Map(demo.d4srules.inputObj -> Map(order -> 1.0)), Map(demo.d4srules.outputObj -> Map(system -> DEV130PHYSTEST)))), Map(key -> input, value -> Map(demo.d4srules.inputObj -> Map(order -> 1.0)))), facts -> List(Map(key -> input, value -> Map(org.drools.core.common.DefaultFactHandle -> Map(external-form -> 0:1:1400441403:1400441403:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj))))))))

As an alternative we could also start with the JSON:
{
“type”: “SUCCESS”,
“msg”: “Container D4SContRules successfully called.”,
“result”: {
“execution-results”: {
“results”: [
{
“key”: “”,
“value”: 1
},
{
“key”: “output”,
“value”: [
{
“demo.d4srules.inputObj”: {
“order”: 1
}
},
{
“demo.d4srules.outputObj”: {
“system”: “DEV130PHYSTEST”
}
}
]
},
{
“key”: “input”,
“value”: {
“demo.d4srules.inputObj”: {
“order”: 1
}
}
}
],
“facts”: [
{
“key”: “input”,
“value”: {
“org.drools.core.common.DefaultFactHandle”: {
“external-form”: “0:1:1640380:1640380:1:DEFAULT:NON_TRAIT:demo.d4srules.inputObj”
}
}
}
]
}
}
}

Thankx for your help!

Regards
Michael

I’d recommend using PlayJson

you’d first turn your JSON String into a JsObject like so:

Json.parse(jsonString).as[JsObject]

and then you’d can just dig through the nested structure (see https://www.playframework.com/documentation/2.5.x/ScalaJson)

You could use lenses for easy accessing nested structures. There are plenty of libraries that provides lenses, common choices are Monocle and Shapeless.

Curious about that actually, casper, what would scalaz or shapeless code to achieve that look like (roughly)?

You can’t easily get there from here. The type you have is Option[Map[String,Object]] because some values are Strings (and maybe Double’s), some are Map, and some are List. You’ll want to retain a JSON AST to easily manipulate the result. The Lift AST has a deep query which could find all the values of system. With others you’ll need to write a deep query yourself or know the path you need to access system.

You could abuse Scala using .isInstanceOf/.asInstanceOf or pattern matching (to do the same thing) but avoiding a JSON library’s support is not the right way to handle this task.

As someone relatively new to scala, what is the point of the the built-in JSON parser then? I actually searched around because I found this question interesting, and the answer is always to use some other library.
But then why is that default implementation there? Making a JSON parser turns out to be quite simple, and AFAICT the built-in one is painful to use because of the way it returns generic types in various places, instead of defining an appropriate AST. Using it then becomes an exercise in fighting the type-system. Why does the built-in version even exist then?

Built in where? (honest question) The standard library doesn’t have a JSON parser.

There is no further point to scala.util.parsing.json. It has been formally deprecated, but the Scala release containing the deprecation (namely 2.12.3) hasn’t shipped yet.

see let's deprecate scala.util.parsing.json · Issue #99 · scala/scala-parser-combinators · GitHub for history & details

P.S. note that all of scala-parser-combinators has been unbundled as of Scala 2.13.0-M1; see https://github.com/scala/scala/pull/5790

The point was they (I include the built-in XML support too) seemed like a good idea at the time they were added. Over time and with experience folks realized that you could get further with other libraries.

You can find a solution for this issue here:


Greetings!
Michael

Hi @michael.hornung, I gone through your above question and its solution, but its giving only the key-value of current provided node, by which we can’t understand that what is the exact hierarchy of this with parent node. I want to get Parent to child relation too with values, also in case of siblings, relation should be incremental to make unique identity.

Can you please help me with this question, where INPUT and Expected output is given.

Hi. I think for the requirement it would be better to use a framework like https://circe.github.io/circe/cursors.html