code: public synchronized int getDataStartIndex() {
          if (dataStartIndex == null) {
              dataStartIndex = 1;
              // check all the <tr>'s in the <tbody> until we find the 1st <tr> that has <td>'s. Then we know we have a
              // row where the data starts. If there are columns in the <tbody>, there will be <th>'s for those rows.
              List<WebElement> allRows = null;
              String xPath = getXPathBase() + "tr";
              try {
                  allRows = HtmlElementUtils.locateElements(xPath);
              } catch (NoSuchElementException e) {
                  // if there is no tr in this table, then the tbody must be empty, therefore columns are not in the tbody
                  return 1;
              }
  
              if (allRows != null) {
                  for (WebElement row : allRows) {
                      if (!row.findElements(By.xpath("td")).isEmpty()) {
                          break;
                      }
                      dataStartIndex++;
                  }
              }
          }
  
          return dataStartIndex;
      }
docs: The row index where the contents of the table's data start.<br/>