Forum Discussion

krogold's avatar
krogold
Regular Contributor
3 years ago
Solved

decoding a string that contains a json that contains an array

Hello,

I have problems with converting strings to json.

Typically I have requests that send me a String response like the one below and I have to compare it with another request's result. The second request gives almost the same result, the sole difference being the order of elements in the array (value = [{type=DAILY  ...).

In my groovy script, if I compare the strings results that I get from my requests, it fails (due to different order).

If I try to use a jsonSlurper, I get errors.I thought it could work.

Is there another way I can parse the responses so I can compare each element one by one ?

 

Value to compare :
{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, timeProgramMode=TIME, startDate=2019-02-28, time=08:10:29}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}

 

Reference value :
{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, time=08:10:29, timeProgramMode=TIME, startDate=2019-02-28}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}
  • Hello krogold

     

    The content of your example values are not valid JSON, so it is no wonder that your JSONSlurper attempt is throwing errors.  I am not familiar with a tool that will parse this format, so breaking it down into the lowest common denominator is what I would do... 

     

    Since the format is basically static between the two values you want to compare, how about just splitting each the same way (with a little tweak for a common difference), then sorting so that they are both in the same order, then compare the sorted results.  A basic sanity check is that they both split into an equal number of elements.  The next check could be line by line of the sorted results to see if there are differences.  The following code compares the two string values you supplied.  The run of this groovy script shows they are equal.  To see a failure, modifying either "refStr" or "compStr" (i.e. add an extra character in a word) to trigger an assertion error. 

     

    Regards,

    TNeuschwanger

     

    log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" start...';
    log.info "";
    
    def refStr = "{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, time=08:10:29, timeProgramMode=TIME, startDate=2019-02-28}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}";
    refStr = refStr.replaceAll('}', '');   // without this, there is a close brace whose result is only differentiated by its existance
    def refStrList = refStr.split();
    def refStrListSorted = refStrList.sort();
    
    log.info "refStrList.size()=" + refStrList.size();
    refStrList.each { element ->
       log.info "element=" + element;
    };
    log.info "";
    log.info "";
    refStrListSorted.each { element ->
       log.info "element=" + element;
    };
    
    
    log.info "";
    log.info "==================================================";
    log.info "";
    
    def compStr = "{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, timeProgramMode=TIME, startDate=2019-02-28, time=08:10:29}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}";
    compStr = compStr.replaceAll('}', '');  // without this, there is a close brace whose result is only differentiated by its existance
    def compStrList = compStr.split();
    def compStrListSorted = compStrList.sort();
    
    log.info "compStrList.size()=" + compStrList.size();
    compStrList.each { element ->
       log.info "element=" + element;
    };
    log.info "";
    log.info "";
    compStrListSorted.each { element ->
       log.info "element=" + element;
    };
    
    
    log.info "";
    log.info "==================================================";
    log.info "";
    
    // sanity check...
    log.info "refStrList.size()=" + refStrList.size();
    log.info "compStrList.size()=" + compStrList.size();
    assert refStrList.size().equals(compStrList.size()), "Mismatch - There are ${refStrList.size()} reference values and ${compStrList.size()} compare values";
    
    // sorted line by sorted line check...
    refStrListSorted.eachWithIndex { refValue, idx ->
       def compValue = compStrListSorted[idx];
       if ( refValue != compValue ) {
          log.info "refValue=" + refValue + "  " + idx;
          log.info "compValue=" + compValue + "  " + idx;
          assert refValue.equals(compValue), "Mismatch - At index $idx the referece value '$refValue' does not match the comparison value '$compValue'";
       };
    };
    
    // If we get here, then the contents are equal
    log.info "";
    log.info "   ***  Reference and Compare strings are equal  ***";
    
    log.info "";
    log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';

       

3 Replies

  • TNeuschwanger's avatar
    TNeuschwanger
    Champion Level 2

    Hello krogold

     

    The content of your example values are not valid JSON, so it is no wonder that your JSONSlurper attempt is throwing errors.  I am not familiar with a tool that will parse this format, so breaking it down into the lowest common denominator is what I would do... 

     

    Since the format is basically static between the two values you want to compare, how about just splitting each the same way (with a little tweak for a common difference), then sorting so that they are both in the same order, then compare the sorted results.  A basic sanity check is that they both split into an equal number of elements.  The next check could be line by line of the sorted results to see if there are differences.  The following code compares the two string values you supplied.  The run of this groovy script shows they are equal.  To see a failure, modifying either "refStr" or "compStr" (i.e. add an extra character in a word) to trigger an assertion error. 

     

    Regards,

    TNeuschwanger

     

    log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" start...';
    log.info "";
    
    def refStr = "{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, time=08:10:29, timeProgramMode=TIME, startDate=2019-02-28}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}";
    refStr = refStr.replaceAll('}', '');   // without this, there is a close brace whose result is only differentiated by its existance
    def refStrList = refStr.split();
    def refStrListSorted = refStrList.sort();
    
    log.info "refStrList.size()=" + refStrList.size();
    refStrList.each { element ->
       log.info "element=" + element;
    };
    log.info "";
    log.info "";
    refStrListSorted.each { element ->
       log.info "element=" + element;
    };
    
    
    log.info "";
    log.info "==================================================";
    log.info "";
    
    def compStr = "{satisfied=true, dynamic_href/properties/triggers, name=triggers, value={satisfied=true, dynamic_href/properties/triggers, name=triggers, value=[{type=DAILY, description=null, configuration={allXDays=1, timeProgramMode=TIME, startDate=2019-02-28, time=08:10:29}, id=guid], metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}, metadata={satisfied=true, href=/m2m/fim/metadata/items/com.hager.domovea.automation.sequence.Sequence/properties/triggers, name=null, description=null, type=null, classes=null, regex=null, min=null, max=null, step=null, enumeration=null, beanMetadata=null, readable=null, writable=null, eventable=null, asyncStatusPropertyName=null, attributes=null}, asyncStatusProperty=null}";
    compStr = compStr.replaceAll('}', '');  // without this, there is a close brace whose result is only differentiated by its existance
    def compStrList = compStr.split();
    def compStrListSorted = compStrList.sort();
    
    log.info "compStrList.size()=" + compStrList.size();
    compStrList.each { element ->
       log.info "element=" + element;
    };
    log.info "";
    log.info "";
    compStrListSorted.each { element ->
       log.info "element=" + element;
    };
    
    
    log.info "";
    log.info "==================================================";
    log.info "";
    
    // sanity check...
    log.info "refStrList.size()=" + refStrList.size();
    log.info "compStrList.size()=" + compStrList.size();
    assert refStrList.size().equals(compStrList.size()), "Mismatch - There are ${refStrList.size()} reference values and ${compStrList.size()} compare values";
    
    // sorted line by sorted line check...
    refStrListSorted.eachWithIndex { refValue, idx ->
       def compValue = compStrListSorted[idx];
       if ( refValue != compValue ) {
          log.info "refValue=" + refValue + "  " + idx;
          log.info "compValue=" + compValue + "  " + idx;
          assert refValue.equals(compValue), "Mismatch - At index $idx the referece value '$refValue' does not match the comparison value '$compValue'";
       };
    };
    
    // If we get here, then the contents are equal
    log.info "";
    log.info "   ***  Reference and Compare strings are equal  ***";
    
    log.info "";
    log.info 'Test Step "' + testRunner.runContext.currentStep.name + '" done...';

       

  • nmrao's avatar
    nmrao
    Champion Level 3

    Is the part of response?
    Not sure how the data is represented. Possible to show raw response please? And what data are you extracting from response? Need not be exact data, but similar data structures so that you can make changes as per your data later.

    Assuming that you are trying a rest request.

    • krogold's avatar
      krogold
      Regular Contributor

      Well, I realized that some extra processing occurred on requests output that were the source of the problem.

      I went through it and corrected some things, now I have a correct Json output that I can deal with.

       

      thanks for your time