Почему я получаю исключение «Индекс за пределами границ»? - PullRequest
0 голосов
/ 13 февраля 2019

Я пытаюсь исправить уже написанный код, который касается получения сетки с веб-страницы.В настоящее время код выглядит следующим образом:

 public static Grid getGrid(String gridXpath) {

    Grid grid = new Grid();
    String html = getWebDriver().findElement(By.xpath(gridXpath)).getAttribute("outerHTML");
    Document doc = Jsoup.parse(html);

    String paginationType = getPaginationType(gridXpath);
    grid.setPaginationType(paginationType);

    // get headers
    Element table = doc.select("table").get(0);
    Elements headers = table.select("th");
    table = doc.select("table").get(doc.select("table").size() - 1);
    Elements bodies = table.select("tbody");
    Elements rows = bodies.select("tr");
    Elements detailRows = bodies.select("tr.k-detail-row");

    for (Element th : headers) {
        if (th.hasClass("k-header") && !th.hasClass("k-hierarchy-cell")) {
            if (th.html().contains("class=\"second-row\"")) {
                Element subHeader = th.selectFirst("span.second-row");
                grid.addSubHeader(subHeader.text());
                th.select("span.second-row").remove();
                grid.addHeader(th.text());
            } else {
                grid.addHeader(th.text());
                grid.addSubHeader(null);
            }
        } else if (!th.hasClass("k-hierarchy-cell")) {
            grid.addHeader(th.text());
            grid.addSubHeader(null);
        }
    }
    // add detail row header if it exists
    if (!detailRows.isEmpty()) {
        grid.addHeader("detail");
        grid.addSubHeader("detail");
    }

    // get rows
    for (Element tr : rows) {
        Row row = grid.new Row();
        if (tr.hasClass("k-master-row")) {
            Elements cells = tr.select("td");
            for (Element td : cells) {
                Cell cell = grid.new Cell();
                cell.addCellLocation(td.cssSelector());
                if (td.attr("role").equalsIgnoreCase("gridcell")) {
                    if (td.html().contains("onclick=")) {
                        Element button = td.selectFirst("button");
                        cell.addCellControl(button.cssSelector());
                        td.select("button").remove();
                    } else {
                        cell.addCellControl(null);
                    }
                    if (td.html().contains("span")) {
                        if (td.html().contains("class=\"second-row\"")) {
                            Element subCell = td.selectFirst("span.second-row");
                            if (subCell.text().isEmpty()) {
                                cell.setSubText(null);
                            } else {
                                cell.setSubText(subCell.text());
                            }
                            td.select("span.second-row").remove();
                            if (td.text().isEmpty()) {
                                cell.setText(null);
                            } else {
                                cell.setText(td.text());
                            }
                        } else {
                            cell.setText(td.select("span").text());
                            td.select("span").remove();
                            cell.setSubText(td.text());
                        }
                    } else {
                        cell.setText(td.text());
                        cell.setSubText(null);
                    }
                    row.addCell(cell);
                }
            }
            row.addCell(createCell(detailRows.get((grid.getRows().size())).cssSelector(), detailRows.get((grid.getRows().size())).text()));
            grid.addRow(row);
        } else if (!tr.hasClass("k-detail-row")) {
            Elements cells = tr.select("td");
            for (Element td : cells) {
                Cell cell = grid.new Cell();
                cell.addCellLocation(td.cssSelector());
                if (td.html().contains("<input")) {
                    Element input = td.selectFirst("input");
                    cell.setText(null);
                    cell.setSubText(null);
                    cell.addCellControl(input.cssSelector());

                } else {
                    cell.setText(td.text());
                    cell.setSubText(null);
                    cell.addCellControl(null);
                }
                row.addCell(cell);

                if (td.hasAttr("colspan")) {
                    for (int i = 1; i < Integer.valueOf(td.attr("colspan")); i++) {
                        row.addCell(createCell(null, null));
                    }
                }
            }
            grid.addRow(row);
        }
    }

Этот код работает нормально, если в сетке есть только одна страница данных, но он падает, когда их несколько.Чтобы решить эту проблему, я попытался добавить код нумерации страниц.Пока у меня есть следующее:

if (paginationType != null && getCurrentPage(gridXpath, grid.getPaginationType()) != getLastPageNumberShownInPagination(gridXpath, grid.getPaginationType())) {
        do {
            gotoNextPage(gridXpath, grid.getPaginationType());

            html = getWebDriver().findElement(By.xpath(gridXpath)).getAttribute("outerHTML");
            doc = Jsoup.parse(html);


            table = doc.select("table").get(0);
            table = doc.select("table").get(doc.select("table").size() - 1);
            bodies = table.select("tbody");
            rows = bodies.select("tr");
            detailRows = bodies.select("tr.k-detail-row");

            for (Element tr : rows) {
                Row row = grid.new Row();
                if (tr.hasClass("k-master-row")) {
                    Elements cells = tr.select("td");
                    for (Element td : cells) {
                        Cell cell = grid.new Cell();
                        cell.addCellLocation(td.cssSelector());
                        if (td.attr("role").equalsIgnoreCase("gridcell")) {
                            if (td.html().contains("onclick=")) {
                                Element button = td.selectFirst("button");
                                cell.addCellControl(button.cssSelector());
                                td.select("button").remove();
                            } else {
                                cell.addCellControl(null);
                            }
                            if (td.html().contains("span")) {
                                if (td.html().contains("class=\"second-row\"")) {
                                    Element subCell = td.selectFirst("span.second-row");
                                    if (subCell.text().isEmpty()) {
                                        cell.setSubText(null);
                                    } else {
                                        cell.setSubText(subCell.text());
                                    }
                                    td.select("span.second-row").remove();
                                    if (td.text().isEmpty()) {
                                        cell.setText(null);
                                    } else {
                                        cell.setText(td.text());
                                    }
                                } else {
                                    cell.setText(td.select("span").text());
                                    td.select("span").remove();
                                    cell.setSubText(td.text());
                                }
                            } else {
                                cell.setText(td.text());
                                cell.setSubText(null);
                            }
                            row.addCell(cell);
                        }
                    }
                    row.addCell(createCell(detailRows.get((grid.getRows().size())).cssSelector(), detailRows.get((grid.getRows().size())).text()));
                    grid.addRow(row);
                } else if (!tr.hasClass("k-detail-row")) {
                    Elements cells = tr.select("td");
                    for (Element td : cells) {
                        Cell cell = grid.new Cell();
                        cell.addCellLocation(td.cssSelector());
                        if (td.html().contains("<input")) {
                            Element input = td.selectFirst("input");
                            cell.setText(null);
                            cell.setSubText(null);
                            cell.addCellControl(input.cssSelector());

                        } else {
                            cell.setText(td.text());
                            cell.setSubText(null);
                            cell.addCellControl(null);
                        }
                        row.addCell(cell);

                        if (td.hasAttr("colspan")) {
                            for (int i = 1; i < Integer.valueOf(td.attr("colspan")); i++) {
                                row.addCell(createCell(null, null));
                            }
                        }
                    }
                    grid.addRow(row);
                }
            }

Большая часть этого кода является просто копией / вставкой из предыдущего кода, но когда я запускаю его, я получаю сообщение об ошибке 'java.lang.IndexOutOfBoundsException: Index 10за пределами длины 3 'из следующей строки:

row.addCell (createCell (detailRows.get ((grid.getRows (). size ())). cssSelector (), detailRows.get ((grid.getRows (). size ())). text ()));

Я не уверен, почему эта строка кода работает до нумерации страниц, но не работает после.Любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ: Таким образом, выясняется, что проблема состоит в том, что сетка содержит все данные с предыдущей страницы, и поэтому, когда я использую grid.getRows (). Size (), он считаетсявсе строки, а не только строки с текущей страницы.Любые предложения о том, как я могу использовать только строки на текущей странице?

Могу ли я создать новую сетку и добавить ее в существующую сетку, как только у меня будут все данные?

1 Ответ

0 голосов
/ 13 февраля 2019

Обратите внимание, что размер List не равен фактическим доступным List индексам.Для List с 2 элементами вы получите размер 2, но фактические элементы можно получить с помощью list.get(0) и list.get(1);.

Чтобы решить вашу проблему, просто вычтите один из вашего спискаразмер:

detailRows.get((grid.getRows().size() - 1) 
...