Create a JSON file using a for each loop and Map – it repeats the first element value across all iterations of the for loop
For each of the loops below, do not add all six values in the list. Instead, it just repeats the first value 6 times. Also a JSON file created with the same input.
Note: I also mentioned this link, but didn’t get the expected output. Javascript each loop over JSON only getting first element?
The next steps are,
1. Find the tr element and read the data one by one
2. Map is also used to store these values when reading
3. Add the mapped values to the Jason array.
Below is my code
public static void GetPercentageValue(String locatorType, String locatorValue) throws FileNotFoundException
{
locatorType="xpath";
locatorValue="//div[@class='content shadow']/div/child::table[1]/tbody/tr";
List<WebElement> tableRows=findTheElements(locatorType,locatorValue);
for(WebElement tablerow : tableRows)
{
Map map = new LinkedHashMap(tableRows.size());
row=row+1;
String rowKeys=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr['"+row+"']/td[1]")).getText();
String price=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr['"+row+"']//input")).getAttribute("value");
System.out.println("RowDesc & Price: "+rowKeys+" "+price);
map.put(rowKeys, price);
jArr.add(map);
}
jaObj.put("Values", jArr);
PrintWriter pWriter = new PrintWriter(mbsDataPath1);
pWriter.write(jaObj.toJSONString());
pWriter.flush();
pWriter.close();
}
The expected output should be:
RowDesc & Price: <80.000 0
RowDesc & Price: 80.000-150.000 2
RowDesc & Price: 150.000-300.000 10
RowDesc & Price: 300.000-500.000 15
RowDesc & Price: >500.000 18
The actual output of the code above is:
RowDesc & Price: <80.000 0
RowDesc & Price: <80.000 0
RowDesc & Price: <80.000 0
RowDesc & Price: <80.000 0
RowDesc & Price: <80.000 0
Solution
The workaround is simple. Your XPATH is incorrect
String rowKeys=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr['"+row+"']/td[1]")).getText();
String price=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr['"+row+"']//input")).getAttribute("value");
How you pass the row
variable is critical!
You pass it as a string (in the context of Xpath) instead of a number.
Let’s assume row=1
Your XPath looks like this:
String rowKeys=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr['1']/td[1]")).getText();
Do you see it now? You create tr[‘1’] instead of tr[1]
and are – it really matters.
If you pass it as tr['1']
, then you will match all tr
elements, not a specific index. It makes Selenium always match the first element in all tr
lists!
Just change Xpath to:
String rowKeys=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr["+row+"]/td[1]")).getText();
String price=tablerow.findElement(By.xpath("//div[@class='content shadow']/div/child::table[1]/tbody/tr["+row+"]//input")).getAttribute("value");