Forum Discussion

dudeed's avatar
dudeed
Former Employee
Nov 13, 2020

Unwinding nested JSON-serialized strings at the root value level

 

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

    • dudeed's avatar
      dudeed
      Former Employee

      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

Resources