2014-10-17 3 views
0

Я пытаюсь получить последние строки x (в данном случае последние 5 строк) таблицы с помощью Jsoup. Но перед тем, как выбрать последние 5 детей, мне нужно применить некоторые фильтры для запроса выбора.Выбор последних x детей в Jsoup

Elements ptr = ptable.select("tr:gt(0):contains("+patern+")"); 

Это то, что я должен выбрать в первую очередь. Поскольку таблица содержит множество ненужных строк, я фильтрую первую строку (содержащую заголовки столбцов) и избавляясь от бесполезных строк, я использую текст patern, чтобы выбрать то, что мне нужно. (эта часть работает без проблем)

После этого шага мне нужно получить последние 5 результатов от остальных элементов. Я пробовал это

Elements ptr = ptable.select("tr:gt(0):contains("+patern+"):nth-last-child(-n+5)"); 

Но это не сработало. Пробовал nth-last-child (5), но все еще не работает. В качестве последнего результата я попытался;

Elements ptd = ptr.select("td:nth-last-child(-n+"+Integer.toString(ptd1.size()*5)+")"); 

Чтобы выбрать результаты как td, но все еще не работает. ("ptd1.size()" возвращает количество столбцов.)

Ну, в конце концов, я не смог получить последние 5 элементов после применения фильтров, которые я хочу. Нужно ли их выбирать после применения фильтров «gt (0)» и «содержит (« + patern + »)»?

пс. Содержимое таблицы является динамическим, поэтому я не могу пропустить первые строки x, чтобы получить последние 5.

ответ

0

Простейшим решением является создание подсписника из отфильтрованного списка соответствующих элементов. Я написал простой пример в Groovy - https://gist.github.com/wololock/ade801b2ccf65f21de4d Что вы можете видеть, что в первую очередь вы отфильтровать все строки, которые не заинтересованы в:

Elements elements = document.select('table#test tr:contains(ID)') 

В этом примере мы не заинтересованы в строках который не содержит ключевое слово «ID» для простоты. Тогда мы просто взять последние п элементов из нашего списка отфильтрованных элементов:

int numberOfLastElements = 3 
List<Element> sublist = elements.subList(elements.size() - numberOfLastElements, elements.size()) 

Имейте в виду, что в вашем коде вы должны проверить, если число отфильтрованных элементов больше, чем число вы пытались извлечь - без это вы столкнетесь с ArrayIndexOutOfBoundsException. Последнее, что мы проверяем в этом коде, если результат содержит элементы, которые мы ожидаем:

assert sublist.every { 
    ['ID: 4', 'ID: 5', 'ID: 6'].contains(it.select('td:first-child').html()) 
} 

Это простое утверждение добавляется для целей тестирования и вы не должны добавить его в свой рабочий код. Он проверяет только, содержит ли каждый элемент в фильтрованном подсписке одно из заданного содержимого в первом элементе td.

Этот пример написан в Groovy, решение Java будет почти таким же.

+0

Я использовал этот код 'Elements sublist = (Elements) ptr.subList (ptr.size() - 5, ptr.size());' но я получил эту ошибку. Я делаю что-то неправильно? 'java.lang.ClassCastException: java.util.AbstractList $ SubAbstractListRandomAccess не может быть передан в org.jsoup.select.Elements' – Soulcry

+0

Это была моя ошибка - в Java это должно быть похоже на« Список sublist = ptr.subList (ptr.size() - 5, ptr.size()); '. Groovy отлично справляется с кастингом в этом случае ('List -> Elements' благодарит за динамические улучшения языка), но в Java он должен быть статически корректным. Я исправил ответ и образец кода в Gist. Извините за неудобства. –

+0

Спасибо, сейчас работает. – Soulcry

Смежные вопросы