Options

Compare JSON-Objects

MarHanMarHan Member Posts: 33
Hi folks,

how do I compare the equality of two JSON objects during runtime without breaking out into the .net world?

I'd like to have something like this:

if MyJsonObject1.Equals(MyJsonObject2) then ...

A workaround could be converting both to text, removing all whitespaces, probably lowercasing everything and then compare the texts. But that will not work if the order of json tokens is different inside the objects:
{ "name": "Adam", "age": "26"} vs. { "age": "26", "name": "Adam"}

Thanks in advance

Markus

Answers

  • Options
    dreezdreez Member Posts: 68
    edited 2023-12-18
    I don't think there is anything in AL that compares two JObjects, so I would try to implement something like this:
    local procedure AreJObjectsEqual(JObject1: JsonObject; JObject2: JsonObject): Boolean
    var
        JToken1: JsonToken;
        JToken2: JsonToken;
        KeyAsText: Text;
    begin
        if JObject1.Keys().Count() <> JObject2.Keys().Count() then
            exit;
    
        foreach KeyAsText in JObject1.Keys() do begin
            if not JObject2.Contains(KeyAsText) then
                exit;
            
            JObject1.Get(KeyAsText, JToken1);
            JObject2.Get(KeyAsText, JToken2);
    
            if not AreJTokensEqual(JToken1, JToken2) then // the function to implement
                exit;
        end;
    
       exit(true);
    end;
    
  • Options
    MarHanMarHan Member Posts: 33
    Some "handmade" stuff like that could work for simple json objects but I'm dealing with CMIS objects that have properties like that
    {
    "properties": {
    "repo[201]": {
                "id": "repo[201]",
                "type": "string",
                "cardinality": "multi",
                "value": [
                    "277",
                    "306"
                ]
            },
    "repo[192]": {
                "id": "repo[192]",
                "type": "string",
                "cardinality": "multi",
                "value": [
                    "200"
                ]
            }
    }
    }
    

    Not sure if I want to implement such a comparer on my own
  • Options
    dreezdreez Member Posts: 68
    Implementing this isn't straightforward—it involves covering many cases. If there aren't any existing methods within AL to compare JSON Objects then you might want to use external functions called with HTTP Request.
  • Options
    MarHanMarHan Member Posts: 33
    The thing is, that I need that for writing automated tests. In AL, I create a json object to be sent via http to an other system. In order to write a test method for my code, I need a way to compare the json object my tested procedure created with the json object that it should have created. If they're unequal, the test must fail as somebody messed up the json creation procedure.

    I do not want to send the two json objects to an external service to have them compared everytime I run my tests. That doesn't make sense.

    I found out that the Newtonsoft implementation has something like JToken.DeepEquals (Link) - Sadly this seems not to be available in BC :-(
Sign In or Register to comment.