问题
Given my json response body
[{"brukergruppeSperret":false,"virksomhetsnavn":"HELFO","brukerGruppe":"Brukerstøtte"},{"brukergruppeSperret":false,"virksomhetsnavn":"Klubbgaten Legesenter","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Sjøsiden Legesenter","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Athene legekontor Helsedirektoratet","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Xeon Legekontor","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Østmarka legekontor","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Hultemyra shamansamling","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"AMIS Testsenter","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"GLØSHAUGEN LEGESENTER DA","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"Helse Møre og Romsdal HF","brukerGruppe":"Lege"},{"brukergruppeSperret":false,"virksomhetsnavn":"St. Olavs hospital HF","brukerGruppe":"Saksbehandler"},{"brukergruppeSperret":false,"virksomhetsnavn":"HELSEDIREKTORATET","brukerGruppe":"Saksbehandler"},{"brukergruppeSperret":false,"virksomhetsnavn":"Østmarka legekontor","brukerGruppe":"Saksbehandler"}
I am using
.check(jsonPath("$..[?(@.brukerGruppe=='Lege')]").saveAs("valgtBrukergruppe"))
to obtain the first occurence in the array/json body with value "Lege" for the value "brukergruppe.
However the value "Lege" appears several times as you can see in the pasted json responsebody.
I want to obtain just the first value of "Lege" and save the INDEX-VALUE of that element in the response array/json.
Is there some logic that could be implemented to support this or a function (Scala/gatling) that returns the index-value?
I was thinking in the lines of something like this:
.check(jsonPath("$..[?(@.brukerGruppe=='Lege')]").INDEXVALUEOF.saveAs("valgtBrukergruppe"))
Or do I need to include some sort of conditioning here with if/else or something similar?
I have this representation of the implementation in C# and want to reproduce in Gatling using Scala.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Utilities
{
public static class JsonParser
{
private static String[] parseJsonObject(String aJsonObject)
{
return aJsonObject.Split('{', ',', '}');
}
private static String[] parseJsonObject(String aJsonObject, String aSkip)
{
String[] elements = parseJsonObject(aJsonObject);
int pos = getArrayPositionOf(aSkip, elements);
if (pos > 0) return elements.Skip(pos).ToArray();
else return elements;
}
private static String extractValueAsTextualNumber(String aStringThatHoldsValue, int aStartPos, int aEndPos)
{
return aStringThatHoldsValue.Substring(aStartPos, aStringThatHoldsValue.Length - aStartPos);
}
private static String extractValueWithoutDoubleFnut(String aStringThatHoldsValue, int aStartPos, int aEndPos)
{
aStartPos++; // skip leading '"' (doubble-fnut)
return aStringThatHoldsValue.Substring(aStartPos, aEndPos - aStartPos); // skip trailing '"' (doubble-fnut) - implicit.
}
public static String getValue(String anAttributeString)
{
int startPos = anAttributeString.IndexOf(':') + 1;
int endPos = anAttributeString.LastIndexOf("\"");
if ((endPos - startPos) > 0) // Then the value behind the : (semi colon) is also surrounded by double fnuts
return extractValueWithoutDoubleFnut(anAttributeString, startPos, endPos);
else
return extractValueAsTextualNumber(anAttributeString, startPos, endPos);
}
public static String getElement(String aElementName, String aJsonObject)
{
return getElement(aElementName, aJsonObject, "");
}
public static String getElement(String aElementName, String aJsonObject, String aSkip){
String[] elementArray;
if(aSkip == "") elementArray = parseJsonObject(aJsonObject);
else elementArray = parseJsonObject(aJsonObject, aSkip);
for (int i = 0; i < elementArray.Length; i++)
{
if (elementArray[i].Contains("\"" + aElementName + "\":"))
{
return getValue(elementArray[i]);
}
}
return "";
}
public static int getNumbersInARowOfSimularElements(String aElementName, String aValueContains, String aJsonObject)
{
return getNumbersInARowOfSimularElements(aElementName, aValueContains, aJsonObject, -1);
}
public static int getNumbersInARowOfSimularElements(String aElementName, String aValueContains, String aJsonObject, int aNotFoundPosition)
{
String[] splittObject = parseJsonObject(aJsonObject);
int position = -1;
for (int i = 0; i < splittObject.Length; i++)
{
if (splittObject[i].Contains("\"" + aElementName + "\":"))
{
position++;
if (splittObject[i].Contains(aValueContains)) return position;
}
}
return aNotFoundPosition;
}
public static int countNumbersOfSimularElements(String aElementName, String aValueContains, String aJsonObject)
{
String[] splittObject = parseJsonObject(aJsonObject);
int count = 0;
for (int i = 0; i < splittObject.Length; i++)
{
if (splittObject[i].Contains("\"" + aElementName + "\":"))
{
if (splittObject[i].Contains(aValueContains)) count++;
}
}
return count;
}
public static List<string> getVariantsOfValue(String aElementName, String aValueContains, String aJsonObject)
{
String[] splittObject = parseJsonObject(aJsonObject);
List<string> variants = new List<string>();
for (int i = 0; i < splittObject.Length; i++)
{
if (splittObject[i].Contains("\"" + aElementName + "\":"))
{
if (splittObject[i].Contains(aValueContains)) {
if (variants.Contains(getValue(splittObject[i])) == false) variants.Add(getValue(splittObject[i]));
}
}
}
return variants;
}
public static String getValueOfNthSimularElement(String aElementName, int aNthPosition, String aJsonObject)
{
String[] splittObject = parseJsonObject(aJsonObject);
int position = -1;
for (int i = 0; i < splittObject.Length; i++)
{
if (splittObject[i].Contains("\"" + aElementName + "\":"))
{
position++;
if (position == aNthPosition) return getValue(splittObject[i]); ;
}
}
return "";
}
private static int getArrayPositionOf(String aElementName, String[] aStringArray)
{
int aNotFoundPosition = -1;
for (int i = 0; i < aStringArray.Length; i++)
{
if (aStringArray[i].Contains("\"" + aElementName + "\":")) return i;
}
return aNotFoundPosition;
}
}
}
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.WebTesting;
using System.Globalization;
using Utilities;
using System.ComponentModel;
namespace Utilities
{
//-------------------------------------------------------------------------
/// This class creates a custom extraction rule
//-------------------------------------------------------------------------
[Description("Looks up the index (first match) of a json attribute that contains a specified substring.\n Based on this index a list of json attributes is stored using the correspondent context variable name list.")]
public class ExtractionRuleJsonLookUpIndex : ExtractionRule
{
private string _lookUpAttribute;
[Description("Name of Json attribute to look up.")]
public string LookUpAttribute
{
get { return _lookUpAttribute; }
set { _lookUpAttribute = value; }
}
private string _containsValue;
[Description("Value of the Json attribute must contain this text to give a match.")]
public string ContainsValue
{
get { return _containsValue; }
set { _containsValue = value; }
}
private string _jsonAttributeLookUpList;
[Description("Comma separated list of Json attributes to extract (one per ContextParameterStoreList).")]
public string JsonAttributeLookUpList
{
get { return _jsonAttributeLookUpList; }
set { _jsonAttributeLookUpList = value; }
}
private string _contextParameterStoreList;
[Description("Comma separated list of context parameters for storing (one per JsonAttributeLookUpList).")]
public string ContextParameterStoreList
{
get { return _contextParameterStoreList; }
set { _contextParameterStoreList = value; }
}
[Description("The index value (ContextParameterValue) that will be stored when no match is found.")]
private int _indexValueWhenNotFound;
public int IndexValueWhenNotFound
{
get { return _indexValueWhenNotFound; }
set { _indexValueWhenNotFound = value; }
}
private Boolean ParameterLenghtTest(int aContextListLength, int aJsonAttributeListLength, ExtractionEventArgs e)
{
Boolean result = false;
if (aContextListLength != aJsonAttributeListLength)
e.Message = String.Format(CultureInfo.CurrentCulture, "Different numbers of context parameters and json attributes in rule: {0}", this.ContextParameterName);
else
result = true;
return result;
}
public override void Extract(object sender, ExtractionEventArgs e)
{
e.Success = false;
String contextStr = "";
String[] jsonAtrributesSplit = null;
String[] contextParametersSplit = null;
if (e.Response.HtmlDocument != null)
{
int selectionIdx = JsonParser.getNumbersInARowOfSimularElements(LookUpAttribute, ContainsValue, e.Response.BodyString, IndexValueWhenNotFound);
e.WebTest.Context.Add(this.ContextParameterName, selectionIdx);
if (selectionIdx != IndexValueWhenNotFound)
{
if ((JsonAttributeLookUpList != "") && (ContextParameterStoreList != ""))
{
jsonAtrributesSplit = JsonAttributeLookUpList.Split(',');
contextParametersSplit = ContextParameterStoreList.Split(',');
if (ParameterLenghtTest(contextParametersSplit.Length, jsonAtrributesSplit.Length, e) == false) return;
for (int loop = 0; loop < jsonAtrributesSplit.Length; loop++)
{
contextStr = JsonParser.getValueOfNthSimularElement(jsonAtrributesSplit[loop], selectionIdx, e.Response.BodyString);
if (contextStr != "") e.WebTest.Context.Add(contextParametersSplit[loop], contextStr);
}
}
}
e.Success = true;
return;
}
e.Message = String.Format(CultureInfo.CurrentCulture, "Not Found: {0}", this.ContextParameterName);
}
}
}
来源:https://stackoverflow.com/questions/62187610/index-of-value-in-json-responsebody-gatling-scala