Wiremock: XPath matching fail - xpath

I am trying to use Wiremock to do request matching.\
This matchXPath is correct when i set the value = 1
"bodyPatterns": [{
"matchesXPath" : "//ipgapi:IPGApiOrderRequest[./v1:Transaction=1]",
"xPathNamespaces": {
"ipgapi": "http://ipg/ipgapi",
"v1": "http://ipg/v1"
}
This is the XML
<ipgapi:IPGApiOrderRequest
xmlns:v1="http://ipg/v1"
xmlns:ipgapi="http://ipg/ipgapi">
<v1:Transaction>1</v1:Transaction>
</ipgapi:IPGApiOrderRequest>
But when i wish to change the value from 1 to abc it return not match.
"bodyPatterns": [{
"matchesXPath" : "//ipgapi:IPGApiOrderRequest[./v1:Transaction='abc']",
"xPathNamespaces": {
"ipgapi": "http://ipg/ipgapi",
"v1": "http://ipg/v1"
}
This is the XML
<ipgapi:IPGApiOrderRequest
xmlns:v1="http://ipg/v1"
xmlns:ipgapi="http://ipg/ipgapi">
<v1:Transaction>abc</v1:Transaction>
</ipgapi:IPGApiOrderRequest>
May i know what mistake i made when trying to do abc matching ? Thanks for helping !

Related

I want to update values ​in an array in an array while using MongoTemplate

First, I will show the state stored in mongodb.
As you can see, it is a structure with a list called replies in a list called comments. And inside replies there is an array called likes.
comments : [
Object1 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
},
Object2 : {
replies : [
likes : [
0 : {},
1 : {}
]
]
}
]
What I want to do here is to insert/subtract a value only from the likes array inside a specific replies structure. I'm currently using Spring boot and have tried the following:
Query query = new Query();
Criteria criteria = Criteria.where("_id").is(new ObjectId(postId))
.andOperator(Criteria.where("comments")
.elemMatch(Criteria.where("_id").is(new ObjectId(commentId))
.andOperator(Criteria.where("replies")
.elemMatch(Criteria.where("_id").is(new ObjectId(replyId)))
)
)
);
query.addCriteria(criteria);
Update update = new Update();
if (state) {
// remove user id
update.pull("comments.$[].replies.$.likes", new ObjectId(userId));
} else {
// add user id
update.push("comments.$[].replies.$.likes").value(new ObjectId(userId));
}
mongoTemplate.updateFirst(query, update, MyEntity.class);
It is an operation to add or remove userId according to boolean state. As a result of the attempt, up to a specific comment is found, but userId is unconditionally entered in the first likes list of the replies list inside the comment. What I want is to get into the likes list inside a specific reply. Am I using the wrong parameter in update.push()? I would appreciate it if you could tell me how to solve it.
Not a direct answer to your question as I'm not experienced with spring's criteria builder, but here's how you would do it in mongo directly, which might help you to figure it out:
You could define arrayfilters allowing you to keep track of the corresponding indices of each comments and replies. You can then use those indices to push a new object at the exact matching indices:
db.collection.update({
_id: "<postId>"
},
{
$push: {
"comments.$[comments].replies.$[replies].likes": {
_id: "newlyInsertedLikeId"
}
}
},
{
arrayFilters: [
{
"comments._id": "<commentId>"
},
{
"replies._id": "<replyId>"
}
]
})
Here's an example on mongoplayground: https://mongoplayground.net/p/eNdDXXlyi2X

Mail merge template : local variable not getting value in if..else

{ MERGEFIELD TableStart:Test}{ SET PLAN {MERGEFIELD Name}="XYZ" "1" "0"}}
{ MERGEFIELD TableEnd:Test }
{ IF { REF PLAN } = "1" "Pass" "Fail"}
In this example always getting result Fail, whether Name is "XYZ" or not.
can anyone suggest further ?
In your case in the SET field you should use IF field to evaluate condition. Please see the following field codes:
{ SET PLAN { IF {MERGEFIELD Name} = XYZ "1" "0"} }
{ IF { REF PLAN } = "1" "Pass" "Fail" }
After executing simple mail merge using the following code:
Document doc = new Document(#"C:\Temp\in.docx");
doc.MailMerge.Execute(new string[] { "Name" }, new string[] { "XYZ" });
doc.Save(#"C:\Temp\out.docx");
The resulting document has the following field codes:
{ SET PLAN XYZ = XYZ "1" "0"} }
{ IF { REF PLAN } = "1" "Pass" "Fail" }
which is properly evaluated with "Pass" text.
Also in MS Word document field whitespaces matters. See the screenshot from MS Word document on my side

xpath matching not working for queryparameters

I am trying to put an AND condition in xpath match on query parameters, however it's not working.
I am creating multiple stubs, wherein uniqueId could contain likewise digits 00000 or 11111 but serviceName will be different. e.g.In first request, uniqueId is 1000001 and serviceName='ABC', in Second request, uniqueId is again 1000001 and serviceName is 'XYZ'. For both response will be different. I have created three stubs one for service ABC, 2nd for service XYZ and third is default without and xpath match.
When I call service with queryparameter contains uniqueId 1000001 and serviceName ABC or XYZ, everytime I get response of default stub.
Passing xml in query parameter
"queryParameters":{
"xmlreqdoc": {
"matchesXPath" : "//*[[local-name()='uniqueId'][text()[contains(.,'00000')]] AND //*[local-name()='serviceName'][text() = 'ABCDEFGH']]"
}
}
I have created stubs with priority given.. and seems like everytime default one gets returned. Following is the request xml
<?xml version="1.0" encoding="UTF-8"?>
<service>
<serviceHeader>
<userId>XXXX</userId>
<password>XXXXX</password>
<serviceName>ABCDEFGH</serviceName>
</serviceHeader>
<serviceBody>
<subServiceName>add</subServiceName>
<uniqueId>00000</uniqueId>
</serviceBody>
</service>
Below is the stub mapping I have created
{
"priority" : 1,
"request": {
"urlPath": "/testMappings",
"method": "GET",
"headers": {
"Content-Type": {
"equalTo": "application/xml"
},
"Accept": {
"equalTo": "application/xml"
}
},
"queryParameters":{
"xmlreqdoc": {
"matchesXPath" : "//*[//[local-name()='uniqueId'][text()[contains(.,'00000')]] AND //*[local-name()='serviceName'][text() = 'ABCDEFGH']]"
}
}
},
"response": {
"status": 400,
"headers": {
"Content-Type" : "application/xml"
},
"fixedDelayMilliseconds": 500,
"bodyFileName": "ERROR.xml"
}
}
Any help or pointers will be highly appreciated. Thanks in advance!!
You've told us the incorrect syntax that you've tried, but you haven't told us what you're trying to achieve, so we can tell you what you did wrong, but we can't tell you how to make it right.
"//*[//[local-name()='uniqueId'][text()[contains(.,'00000')]] AND //*[local-name()='serviceName'][text() = 'ABCDEFGH']]"
Things that are obviously wrong here:
// followed immediately by a predicate
Unnecessary matching on local-name() when there are no namespaces involved
Unnecessary use of text()
Unnecessary use of contains() when you could use =
AND should be and
Perhaps you want //uniqueId = '00000' and //serviceName = 'ABCDEFGH'
//*[uniqueId[contains(text(),'00000')] and //serviceName='ABCDEFGH']
worked for me.

What kind of Java type to pass into Criteria.all()?

I am trying to find a document with an array of tags which match a list of values,
using the MongoDB's $all function through Spring Data MongoDB API for all().
Tag is a embedded document with two fields: type and value.
I am not sure what kind of Java type to pass in to the method as it accepts an array of Objects, tried to pass in an array of Criteria objects into the the function but the output is below:
Query: { "tags" : { "$all" : [ { "$java" : org.springframework.data.mongodb.core.query.Criteria#5542c4fe }, { "$java" : org.springframework.data.mongodb.core.query.Criteria#5542c4fe } ] } }, Fields: { }, Sort: { }
How should I proceed?
I want to achieve the following:
db.template.find( { tags: { $all: [ {type:"tagOne", value: "valueOne"}, {type:"tagTwo", value: "valueTwo"} ] } } )
Edited for clarity:
The code which I used is similar to:
Query query = new Query(baseCriteria.and("tags").all( criteriaList.toArray()))
The criteria list is formed by:
Criteria criteria = new Criteria();
criteria.and("type").is(tag.getType()).and("value").is(tag.getValue());
criteriaList.add(criteria);
OK, I've just found out, the Java type required is org.bson.Document, which you can get using:
criteria.getCriteriaObject()

How can i get avg,sum of sub attribute?

I have problem with writing average query!
In my Rethink db, i have some documents in one table like this:
document1:
{
a:{
last:3
},
b:{
last:4
},
c:{
last:6
},
}
document2:
{
a:{
last:7
},
b:{
last:9
},
c:{
last:2
},
}
document3:
{
a:{
last:5
},
b:{
last:8
},
c:{
last:4
},
}
I want to get average of last attribute in every object like this:
{
sum_a_last:15,
sum_b_last:21,
sum_c_last:12,
avg_a_last:5,
avg_b_last:7,
avg_c_last:4
}
What is the query to return this result?
I believe what you're looking for is
r.db('dbName').table('tableName').avg((doc) => doc('a')('last'));
If you're trying to dynamically look for the last member for all objects in a doc there will obviously be more work.
https://rethinkdb.com/api/javascript/avg/

Resources