Unwinding nested JSON-serialized strings at the root value level

Microsoft

 

I know how to individually drill into a JSON object with parse_json() and tostring() at the appropriate places to get a specific value. Your own docs for parse_json show that:


It's common to have a JSON string describing a property bag in which one of the "slots" is another JSON string.
For example:
let d='{"a":123, "b":"{\\"c\\":456}"}';
print d
In such cases, it isn't only necessary to invoke parse_json twice, but also to make sure that in the second call, tostring is used. Otherwise, the second call to parse_json will just pass on the input to the output as-is, because its declared type is dynamic.
let d='{"a":123, "b":"{\\"c\\":456}"}';
print d_b_c=parse_json(tostring(parse_json(d).b)).c

 

Using the same example for 'd' above, what I want to return is a fully deserialized value for 'd', where I can apply json parsing of a string rep at any level I know is needed, while still resulting in a single

'd'-level output result:

 

{ "a":123, "b": {"c":456 }}

 

Can you show be an example of doing the above?

3 Replies

Hi, @dudeed  

 

This totally works for me:

 

let d='{"a":123, "b":{"c":456}}';
let d_b_c=parse_json(d).b.c;
print d_b_c;

 

Have you mixed two different problems in the same script?

 

By the way: There is no KQL in the "insert code samples" window here on the forum! :unamused::sad:

 

Kind Regards,

Dennes

@DennesTorres Yes, that works because that JSON is not composed of separately nested serializations.

I want to get that output with this specific input (the extra double-quotes and escapes are significant and illustrate the core issue I meant). Another words, the value of "b" was serialized first, then sometime later the entire object containing "a" and "b" was serialized to get this payload logged:

'{"a":123, "b":"{\\"c\\":456}"}' // normal one-level deser would think b = the string literal "{\"c\":456}"

I want a one-liner, if you will, that produces exactly this fully deserialized JSON from the above:

{ "a" : 123, "b" : { "c" :456 } }

One can imagine if this trick works for this simple example, it should extrapolate to deeper nestings as well; my guess is there is no simple way to do this atm - you'd need Gson or Newtonsoft-like deserialization parsing support).

Goal: add a single column to my output which is the fully-unwound deserialization of the nested source value like my example. I expect to specify that the value "b" is a serialization point in some way, to not complicate the scenario with the additional chore of auto-detecting the serialization seams.

hth

Hi, @dudeed ,

 

You can use string manipulation to change the string and only after all the changes you will de-serialize the json.

 

I'm talking about remove the slashes ("\\") remove some quotes and so on. The KQL string replace function even supports regex.

 

Kind Regards,

 

Dennes