I have a response map which has some duplicate values in it. I need to identify them, if possible, had to remove them.
Any xpath query can help me out?
Note: I think xpath 2.0 has 'index-of' function, which not works in iTest 3.4.2
Thanks.
I have a response map which has some duplicate values in it. I need to identify them, if possible, had to remove them.
Any xpath query can help me out?
Note: I think xpath 2.0 has 'index-of' function, which not works in iTest 3.4.2
Thanks.
There are some tricks you can use in XPATH 1.0 to find distinct values. I'm attaching a sample test case that shows one way to do this. The preceding-sibling axis in XPATH is a way to get all of the preceding nodes from a given node under the same parent.
So, for example, if you want to get the distinct values among a list of sibling nodes, you can use an xpath query like this:
//elem[not(. = preceding-sibling::elem)]
This may look weird. But what it is saying is, "Find each elem where its value (.) is not the same as the value of one of its previous sibling elems." This returns a list of elem nodes, and, therefore, gets you a list of those values.
In the attached sample, I broaden this to dealing with a table -- where the unique values are actually in a certain column node of a repeating row node. The principle is the same, but the query becomes slightly more complicated:
//row[not(name = preceding-sibling::row/name)]/name
This one says, "Find all of the rows, where the name in that row is not equal to the name appearing in any of the previous row nodes, then take the name from that row".
This is effectively equivalent to what is much simpler in XPATH 2.0:
distinct-values(//row/name)
Note that our hesitation to moving to XPATH 2.0 is that it is not backward-compatible with XPATH 1.0. (Go figure as to why these guys who invented XPATH 2.0 made that choice!) We want to make very sure that we will never break any test case developed with earlier versions of iTest. If we just switch to XPATH 2.0, that could happen. So we're being careful.
It works. Thanks PaulD.
When I modify xpath as: name //row[name = preceding-sibling::row/name]/name
I get the result as a, c, a
Whereas, I want to get duplicate nodes like 'a' and 'c' only. How to modify this query?
I'm not aware of any way to accomplish this with a single xpath query in XPATH 1.0. However, you can do this using a bit of extra logic in your test case.
First, using the technique already described, you store all of the duplicate values in a list using
//row[name = preceding-sibling::row/name]/name
and store this list in a variable, say, all_duplicates
Then you can do the following:
eval set duplicates {} foreach possible $possible_duplicates if [lsearch -exact $duplicates $possible] < 0 then eval lappend duplicates $possible eval puts "Distinct duplicates are: $duplicates"
The notion is that you have a list of possible duplicates, but there may be duplicates in this list. So you create a new list called "duplicates" that will contain your final list. Then you iterate over all of the possible duplicates. For each of them, you check to see whether it is already in your list (in which case, the lsearch will return the index of where it appears in your list, or -1 if it is not there yet). If it is missing, then you append this item to your list.
You could, of course, put this kind of logic into a reusable procedure if you find yourself needing it more than once. You can pass in the list to be analyzed, and get back the list of unique duplicates.
No one has followed this question yet.