regular expressions: in a JSON array, get the id of the object that has status waiting - regex

I have a JSON response that I want to parse with regular expressions that contains an array of objects like
...
{
"Id":"01",
"Subject":"Sub",
....
"Status":"Completed"
...
},
{
"Id":"02",
"Subject":"Sub",
....
"Status":"Waiting"
...
}
and I want to get the id of the object that has status waiting.
When I parse with "Id": "(.+?)",[\s\S]+?"Subject": "Sub",[\s\S]+?"Status": "Waiting"; it matches from "Waiting" to the first "Id" (backwards); certainly I want the Id of the object that is waiting.

Try this:
{\s*"Id":"(\d+)"[^}]+"Status":"Waiting"\s*}

Try this one:
(?s)"Id":\s*"([^"]+)[^}]*?"Status":\s*"Waiting"
It will work if there is no nested { } between properties Id and Status.

If you can use a Json Parser, please use that.
This will work as long as there are no nested brackets.
{[^{}]*Id":"(\d+)[^{}]*\s"Status":"Waiting"
See it here on Regexr
Your expression
"Id": "(.+?)",[\s\S]+?"Subject": "Sub",[\s\S]+?"Status": "Waiting"
^^^^^^^^
fails here
That part matches anything from the first "Sub", till it finds the first "Status": "Waiting"

Related

JMeter json path extractor and Regular expression combination

I want to extract sys_id for the employee_number does not starting with "C"
{
"items": [{
"sys_updated_on": "2021-01-15 15:04:04",
"sys_id": "60eaa1dc47870d9132f624846d434a",
"employee_number": "C89"
}, {
"sys_updated_on": "2017-12-08 09:26:49",
"sys_id": "c57058e8db8689ca52c4be13961974",
"employee_number": "983"
}, {
"sys_updated_on": "2016-04-08 13:25:00",
"sys_id": "fd413e848716119096ca2d0ebb358e",
"employee_number": "565"
}]
}
I tried multiple JSON Extractor expressions but no luck
$.[?(#.employee_number=~'\d+')].sys_id
$.[?(#.employee_number=~'[0-9]')].sys_id
Need both Xpath and Regular expression combination as the JSON contains many other fields and provided JSON is a small part of that.
I also want to know how to combine the regular expression and JSON
path
If you want to match only numbers in the employee_number - try out the following:
$.items[?(#.employee_number =~ /\d+/)].sys_id
More information:
JsonPath Operators
How to Use the JSON Extractor For Testing
with regards to what you "also want to know" - one post - one question, however I'll give you some hint:

define expression in camunda

I have a process that has a custom model, similar to the following model(get by calling http://localhost:8080/engine-rest/task/{id}/variables/):
{
"Title": {
"type": "String",
"value": "aaa",
"valueInfo": {
}
},
"247f3af4-36cf-72cc-1a95-601f07640674": {
"type": "String",
"value": "{\"Title\":\"AA\",\"Value\":\"BB\"}",
"valueInfo": {
}
}
}
I want to define a expressions at the gates. How should I do this?
I try these:
${ "247f3af4-36cf-72cc-1a95-601f07640674".Value == "AA"}
Or
${ JSON("247f3af4-36cf-72cc-1a95-601f07640674").prop("Value") == "AA"}
Or
${S(247f3af4-36cf-72cc-1a95-601f07640674).prop("Value").stringValue() == "AA"}
But get following errors:
Unknown property used in expression: ${ "247f3af4-36cf-72cc-1a95-601f07640674".Value == "AA"}. Cause: Could not find property Value in class java.lang.String
Error while evaluating expression: ${ JSON("247f3af4-36cf-72cc-1a95-601f07640674").prop("Value") == "AA"}. Cause: Error invoking function 'JSON'
ENGINE-01009 Error while parsing process. Error parsing '${S(247f3af4-36cf-72cc-1a95-601f07640674).prop("Value").stringValue() == "AA"}': syntax error at position 15, encountered 'c7', expected ')'.
What you are showing is the value of a JSON object stored in a process data, right? What is the name of the process data?
In Java you use JSON(), in the process (JavaScript) use S()
(see https://docs.camunda.org/manual/7.17/reference/spin/json/01-reading-json/)
Place S() around the name of your process data to create the object. Then you can use .prop() to navigate it. ${S(myData).prop("xyz")}.
In this example I used the method to read the JSON response of a REST call and then extract a field:
https://github.com/rob2universe/camunda-http-connector-example
You use JSON() around the name of the process data, then you can access the properties
I finally find answer
I must use something like this:
${S(a247f3af4_36cf_72cc_1a95_601f07640674).prop("Value").stringValue() == "AA"}
we must start variable name with character and do'nt use -.

How to get "paymentToken" value using Reg Exp Extractor in Jmeter?

My Response Code Looks like: -
{
"data": {
"transactionId": "04dxf19-xx-42e3-a4f7-75xxa012x4a",
"paymentUrl": "https://wpp-test.wirecard.com/?wPaymentToken=t45QiNvkZX5fYxxxxEEpFz8mcK2ZirBhVMrvuo"
},
"message": "Success.",
"code": "OK",
"appVersion": "2.0.0.47",
"machine": "CHPV345678"
}
and from the above code, I want to extract the value inside = wPaymentToken ( i.e t45QiNvkZX5fYxxxxEEpFz8mcK2ZirBhVMrvuo)
I tried the following options without success -
1) "paymentUrl":
"https://wpp-test.wirecard.com/?wPaymentToken=(.+?)"
2)
wPaymentToken=(.+?)"
Can you please help me , as while checking the value in Debug Sampler it always remains enmpty
Here Is my Test Plan : It contains two REGEX in 1 thread
Here is the reson , why I only want paymentToken because Final URL is not same as the URL that we extracted using JSON
Second option should work fine:
Wouldn't be easier to extract the whole paymentUrl attribute value? It can be done using JSON Extractor with a simple JsonPath expression of $.data.paymentUrl

Regular Expression If 2nd parameter is Enrollment

I have below response
{
"id": "3452",
"enrollable_id": "3452",
"enrollable_type": "Enrollment"
}
{
"id": "3453",
"enrollable_id": "3453",
"enrollable_type": "Task"
}
{
"id": "3454",
"enrollable_id": "3454",
"enrollable_type": "Enrollment"
}
{
"id": "3455",
"enrollable_id": "3455",
"enrollable_type": "Task"
}
I would like to get id [3452 and 3454] only if enrollable_type= Enrollment. This is for jmeter regex extractor so it would be great if I can just use one liner regex to fetch 3452 and 3454.
The RegEx you are looking for is:
_id":\s*"([^"]+(?=[^\0}]+_type":\s*"E))
Try it online!
Explanation
_id":\s*" Finds the place where the enrollment_id is
[^"]+(?= Matches the ID if:
[^\0}]+_type":\s* Finds the place where enrollable_type is
"E Checks if the enrollable type begins with an uppercase E
) End if
( ) Captures the ID
It's important to note that this RegEx will match on valid people and capture the valid ID. This means you will need to get each match's capture rather than just getting each match.
Disclaimer
The above RegEx contains backslashes, which you will need to escape if using the RegEx as a string literal.
This is the RegEx with all necessary-to-escape characters escaped:
_id":\\s*"([^"]+(?=[^\\0}]+_type":\\s*"E))
It's usually a bad idea to parse structured data with just a regex, but if you're intent on going this route then here you go:
"(\d+)"\s*,\s*(?="enrollable_type":\s*"Enrollment")
This assumes that entrollable_type always follows enrollable_id and that everything is quoted consistently with a little allowance for variance in white space. You should be able to handle a little more variance if necessary, such as if you're unsure if can depend on keys or data being quoted (["']?). However, if you can depend on the order of the properties (such as if they type comes before id) then you should abandon using a regex.
Here's a sample working in JavaScript
const text = `{ "id": "3452", "enrollable_id": "3452", "enrollable_type": "Enrollment" } { "id": "3453", "enrollable_id": "3453", "enrollable_type": "Task" } { "id": "3454", "enrollable_id": "3454", "enrollable_type": "Enrollment" } { "id": "3455", "enrollable_id": "3455", "enrollable_type": "Task" }`;
const re = /"(\d+)"\s*,\s*(?="enrollable_type":\s*"Enrollment")/g;
var match;
while(match = re.exec(text)) {
console.log(match[1]);
}
Your response seems to be a JSON one (however it's malformed). If this is the case and it's really JSON - I would recommend going for JSON Extractor instead as regular expressions are fragile, sensitive to markup change, new lines, order of elements, etc. while JSON Extractor looks only into the content.
The relevant JSON Path query would be something like:
$..[?(#.enrollable_type == 'Enrollment')].enrollable_id
Demo:
More information: JMeter's JSON Path Extractor Plugin - Advanced Usage Scenarios
You can extract the data in 2 ways
Using Json Extractor.
To extract data using json extractor response data should follow json syntax rules,
To extract data use the following JSON path in json extractor
$..[?(#.enrollable_type=="Enrollment")].id
and use match no -1 as shown below
To extract data using regular expression extractor use the following regex
id": "(.+?)",\s*(.+?)\s*"enrollable_type": "Enrollment
template : $1$2$3$4$
Match no -1
as shown below
you can see the variables stored using debug sampler
More information
extract variables

How to check the type of a field before checking the value in rethinkdb?

I have few tables in rethinkdb with very varied datasets. Mostly because over time, out of simple string properties complex objects were created to be more expressive.
When I run a query, I'm making sure that all fields exist, with the hasFields - function. But what if I want to run a RegExp query on my Message property, which can be of type string or object. Of course if it is an object, I don't care about the row, but instead of ignoring it, rethinkdb throws the error:
Unhandled rejection RqlRuntimeError: Expected type STRING but found OBJECT in...
Can I somehow use typeOf to first determine the type, before running the query?
Or what would be a good way to do this?
Your question is not 100% clear to me so I'm going to restate the problem to make sure my solution gets sense.
Problem
Get all documents where the message property is of type object or the message property is a string and matches a particular regular expression (using the match method).
Solution
You basically need an if statement. For that, you can use the r.branch to 'branch' your conditions depending on these things.
Here's a very long, but clear example on how to do this:
Let's say you have these documents and you want all documents where the message property is an object or a string that has the substring 'string'. The documents look like this:
{
"id": "a1a17705-e7b0-4c84-b9d5-8a51f4599eeb" ,
"message": "invalid"
}, {
"id": "efa3e26f-2083-4066-93ac-227697476f75" ,
"message": "this is a string"
}, {
"id": "80f55c96-1960-4c38-9810-a76aef60d678" ,
"not_messages": "hello"
}, {
"id": "d59d4e9b-f1dd-4d23-a3ef-f984c2361226" ,
"message": {
"exists": true ,
"text": "this is a string"
}
}
For that , you can use the following query:
r.table('messages')
.hasFields('message') // only get document with the `message` property
.filter(function (row) {
return r.branch( // Check if it's an object
row('message').typeOf().eq('OBJECT'), // return true if it's an object
true,
r.branch( // Check if it's a string
row('message').typeOf().eq('STRING'),
r.branch( // Only return true if the `message` property ...
row('message').match('string'), // has the substring `string`
true,
false // return `false` if it's a string but doesn't match our regex
),
false // return `false` if it's neither a string or an object
)
)
})
Again this query is long and could be written a lot more elegantly, but it explains the use of branch very clearly.
A shorter way of writing this query is this:
r.table('messages')
.hasFields('message')
.filter(function (row) {
return
row('message').typeOf().eq('OBJECT')
.or(
row('message').typeOf().eq('STRING').and(row('message').match('string'))
)
})
This basically uses the and and or methods instead of branch.
This query will return you all registers on table message that have the field message and the field is String.
Cheers.
r.db('test').table('message').hasFields('message')
.filter(function (row) {
return row('message').typeOf().eq('STRING')
})