AFAIK, You cannot do this via the testng.xml file.
It is easy to specify the iterations to be executed without having to know the data set size, but it would be impossible to do that when you are excluding a particular iteration.
The easiest way that I can think of is by plugging in this filtering logic within your data provider. Here's a sample that shows you how to do this :
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class SampleTestClass {
@Test(dataProvider = "dp")
public void testMethod(int value) {
System.out.println("Value is " + value);
}
@DataProvider(name = "dp")
public Object[][] getData() {
Object[][] data = new Object[][]{
{1},
{2},
{3},
{4},
{5}
};
//Calculate how many parameters we will be providing the @Test method for every iteration.
int numberOfParameters = data[0].length;
//Get the list of iterations to exclude from the user as comma separated values
//Here for the sake of example we are simulating that only the 3rd iteration needs to be excluded.
String exclude = System.getProperty("exclude", "3");
if (exclude == null || exclude.trim().isEmpty()) {
return data;
}
//Translate that comma separated values into a list of integers
List<Integer> excludeValues = Arrays.stream(exclude.split(","))
.map(Integer::parseInt).collect(Collectors.toList());
Object[][] finalData = data;
//Now nullify all the rows which we were asked to exclude so that its easy for us to filter out all the non
//null values.
excludeValues.forEach(value -> finalData[value] = null);
Object[] newData = Arrays.stream(data).filter(Objects::nonNull).collect(Collectors.toList()).toArray();
//Lets copy the contents back to the original array
data = new Object[newData.length][numberOfParameters];
for (int i=0;i<newData.length;i++) {
data[i] = (Object[]) newData[i];
}
return data;
}
}