0

Trying to use two && statements within a jsonpath query but I can't get the logic I want performed

   public List<Step> GetBuildSteps()
   {

        var rule1 = "Npm@1";
        var rule2 = "npm build";
        var rule3 = "Npm@0";
        var rule4 = "Build";

        var queryString = string.Format("$..steps[?(@.task == '{0}' &&
  @.displayName =~ /^.*{1}.*$/ ||  @.task == '{2}' && @.displayName =~ 
  /^.*{3}.*$/) ]", rule1, rule2, rule3, rule4);
        return queryJson(queryString);
    }

    private List<Step> queryJson(String queryString)
    {
        var values = json.SelectTokens(queryString).ToList();
        Console.WriteLine(queryString);
        Console.WriteLine(JsonConvert.SerializeObject(values, 
        Formatting.Indented));
        return 
        JsonConvert.DeserializeObject<List<Step>
        (JsonConvert.SerializeObject(values, Formatting.Indented));
    }

Here's my JSON sample:

{
   "steps":[
      {
         "task":"Npm@1",
         "displayName":"Dev - npm build",
         "inputs":{
            "filename":"tsc",
            "arguments":"-p $(build.sourcesDirectory)\\SelfServeAdminExtn"
         },
         "enabled":"false",
         "continueOnError":"true"
      },
      {
         "task":"Npm@1",
         "displayName":"Install Packages",
         "inputs":{
            "filename":"tfx"
         },
         "enabled":"false",
         "condition":"succeededOrFailed()"
      },
      {
         "task":"Npm@0",
         "displayName":"Preprod - Build",
         "inputs":{
            "filename":"copy",
            "arguments":"$(build.sourcesDirectory)\\ config.ts / y"
         }
      }
   ]
}

I expect that the statement ?( condition1 && condition2 || condition3 && condition4) will work but it doesn't. It works only when I do ?(condition1 && condition2) but when I combine with condition3 and condition4, I get an empty list.

dbc
  • 104,963
  • 20
  • 228
  • 340
amelongo
  • 93
  • 11
  • Probably related: [How can I create a JSONPath filter expression containing both AND and OR operators?](https://stackoverflow.com/q/38233178/3744182). – dbc Jan 04 '19 at 21:23
  • @dbc, it's not the json; the errors occurred when I edited the json for this post. But for the sake of the discussion, I created a valid json but that doesn't resolve the issue because I still can't use consecutive && operators – amelongo Jan 04 '19 at 21:26
  • @dbc, yes the lines should be merged – amelongo Jan 04 '19 at 21:32
  • @dbc, again that's the edit; I did; I couldn't paste the entire json so I made some quick edit just to highlight the problem. The json I'm working with has the steps at the root; but just for the sake I will correct the json but it wouldn't solve the heart of my issue; which is consecutive && don't work; and when I try to put ?((contion1 && condition2) || (condition3 && condition4)) I get a formatting error that ( is not valid. That's the hard of my issue, not the json format – amelongo Jan 04 '19 at 21:44
  • @dbc, I added the "steps" property, it should be testable now. The json has the steps properties at its roots; so the query in the code should include the steps. Thanks – amelongo Jan 04 '19 at 21:52
  • OK, looks like it's basically the same problem as [How can I create a JSONPath filter expression containing both AND and OR operators?](https://stackoverflow.com/a/38256828/3744182), namely that `?( c1 && c2 || c3 && c4)` is interpreted as `?( c1 && (c2 || (c3 && c4)))` not `?( (c1 && c2) || (c3 && c4))`. Unfortunately there doesn't seem to be a way to rearrange the logicals to get the grouping you want. Would you be willing to use a workaround involving multiple calls to `SelectTokens()`? – dbc Jan 04 '19 at 22:07
  • @dbc, thanks for your assistance. For anyone with the same issue, I went about this doing this: – amelongo Jan 07 '19 at 23:14

1 Answers1

1

@dbc, thanks for your assistance but I resolve this issue doing this:

 queryString = string.Format("$..steps[?(@.task == '{0}' &&  @.displayName =~
  /^.*{1}.*$/)]", rule1, rule2);

 List<Step> result1 = queryJson(queryString);

 queryString = string.Format("$..steps[?(@.task == '{0}' &&  @.displayName =~
  /^.*{1}.*$/)]", rule3, rule4);

 List<Step> result2 = queryJson(queryString);

 return result1.Union(result2).ToList();
amelongo
  • 93
  • 11