Always get your parameter at the end of the xpath. Move two times over the association.
sorry I just mentioned the user roles as an example but this is not my case. I have a person entity that has a many to many relation with zone entity. and I want when I create a person and linked it with zone 1 and zone 2 , then when I add a new person with the same zones 1 and 2 ,It should not be allowed (as the person with zones should be unique) so on save I retrieve the person from the DB to check if there is any person has the same zone so I should not allow that. but how can I apply that many to many relation on the x path of the retrieve action?
I think you can do that in the same fashion as with the userroles.
On the after before commit, or on a custom save button add a microflow that does the following.
Retrieve all users with the following the xpath:
[not(User_Zone/Module.Zone[not(User_Zone = '[%CurrentUser%]')])]
This retrieves all users that have exactly the same zones as the currentUser, or if you don't want to use currentUser but a given userObject replace it with your variable.
After this retrieve do a count on the list, this is more effecient than using an empty check. If the count is higher than 0 you have a match and your validation should fail.
If it isn't a user object you can still perform an equal operation just use your input variable instead.
e.g. you have an object you save with a custom save button or after commit, lets call it $Person
[not(Person_Zone/Module.Zone[not(Person_Zone = $Person)])]
This will require however that you do a commit before you do the check, as xpath only works in combination with the database.