Я использую HtmlUnit, чтобы получить HtmlTable. Я пытаюсь получить список ячеек каждого столбца.
Пока что в коде, который я пробовал, я могу найти первый столбец. Как я могу перебирать каждый столбец и запускать в них какой-то код?
Я хотел бы убедиться, что все они отсортированы по алфавиту, но мне просто нужно выяснить, где разместить этот код.
Обновлено: я нашел свой ответ. Думаю, я неправильно сформулировал вопрос. Мне нужно было собрать каждую колонку и поместить в отдельную коллекцию. В исходном примере я показал только column1. Но мне нужен КАЖДЫЙ столбец (в зависимости от того, сколько ячеек в каждой строке). Ниже приведен код, который работал. Но, возможно, его удастся оптимизировать лучше.
HtmlPage htmlPage = webClient.getPage("http://localhost:8080/myurl");
HtmlTable myTable = htmlPage.getHtmlElementById("mytable");
// find the number of columns by grabbing the first row and returning the number
// of cells within the first row
int numberOfColumns = myTable.getRows().stream().map(row -> row.getCells()).findFirst().get()
.size();
// initialize columns
List<List<String>> columns = new ArrayList<List<String>>(numberOfColumns);
// initialize new arraylists for each column based upon the number of columns
for (int i = 0; i < numberOfColumns; i++)
columns.add(new ArrayList<>());
// iterate through each column
for (int columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) {
// iterate through each row
for (int rowIndex = 0; rowIndex < myTable.getRows().size(); rowIndex++) {
String asText = myTable.getCellAt(rowIndex, columnIndex).asText();
columns.get(columnIndex).add(asText);
}
}
//iterate through the columns and do stuff!
columns.forEach(a -> {
//do stuff to the column such as verify it was sorted, or sort it yourself etc
System.out.println("column" + a.toString());
a.forEach(b -> {
//do stuff
LOG.info(b);
});
});




Вы можете просто сделать это как часть вашего соединения в виде единого потока:
webClient.getPage("http://localhost:8080/myUrl")
.getHtmlElementById("myTable")
.getRows()
.stream()
.map(row -> row.getCells().stream().findFirst().get().asText())
.sort((o1, o2) -> o1.compareTo(o2)) // make alphabetical
.collect(Collectors.joining("|"));
Если вы хотите получить таблицу в виде списка списков (List<List<HtmlTableCell>>), это сделает
List<List<HtmlTableCell>> table = myTable.getRows().stream()
.map(row -> row.getCells().stream().collect(Collectors.toList())
.collect(Collectors.toList());
Или, если вам не понадобится List позже, вы можете пропустить сбор, чтобы перечислить и вместо этого выполнить свой код.
List<List<HtmlTableCell>> table = myTable.getRows().stream()
.map(row -> row.getCells().stream().collect(Collectors.toList())
.forEachOrdered(cellList -> System.out.println(cellList));
Вы можете собрать его на List из List:
List<List<HtmlTableCell>> columns =
myTable.getRows()
.stream()
.map(row -> row.getCells()
.stream()
.collect(Collectors.toList())
.collect(Collectors.toList());
А потом, когда вам нужно будет войти:
LOG.info(columns.stream()
.flatMap(List::stream)
.map(m -> m.asText())
.sorted() //Sort the list
.collect(Collectors.joining("|")));
Поскольку вы хотите, чтобы List<HtmlTableCell> представлял данные в заданном столбце вашей таблицы html, вам необходимо использовать getCellAt, который принимает индекс строки и индекс столбца.
IntStream.range(0, numberOfColumns)
.mapToObj(colIndex -> IntStream.range(0, numberOfRows)
.mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex)).collect(toList()))
.collect(toList());
где numberOfColumns следует заменить количеством столбцов в вашей HTML-таблице, а numberOfRows следует заменить количеством строк в вашей HTML-таблице.
Это даст List<List<HtmlTableCell>>, где каждый List<HtmlTableCell> - это все ячейки для каждого столбца.
Для полноты, вот как вы можете отсортировать каждый List<HtmlTableCell>, то есть данные каждого столбца.
List<List<HtmlTableCell>> result =
IntStream.range(0, numberOfColumns)
.mapToObj(colIndex -> IntStream.range(0, numberOfRows)
.mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex))
.sorted(Comparator.comparing(HtmlTableCell::asText))
.collect(toList()))
.collect(toList());
и зарегистрируйте это:
// concatenate each cell data of each column separated by a pipe and then separate each column data by a line separator.
String joined = result.stream()
.map(l -> l.stream().map(HtmlTableCell::asText).collect(Collectors.joining("|")))
.collect(Collectors.joining(System.lineSeparator()));
// log it!
LOG.info(joined);
Обратите внимание: если все, что вы делаете, это ведение журнала, то собирать на промежуточный List<List<HtmlTableCell>> не стоит, вы можете получить требуемый результат как:
String joined = IntStream.range(0, numberOfColumns)
.mapToObj(colIndex -> IntStream.range(0, numberOfRows)
.mapToObj(rowIndex -> myTable.getCellAt(rowIndex, colIndex).asText())
.sorted()
.collect(Collectors.joining("|")))
.collect(Collectors.joining(System.lineSeparator()));
LOG.info(joined);