Я пытаюсь получить весь html между двумя тегами h1. Актуальная задача состоит в том, чтобы разбить html на фреймы (главы) на основе тегов h1 (заголовок 1).
Цените любую помощь.
Спасибо, Сунил.
Я пытаюсь получить весь html между двумя тегами h1. Актуальная задача состоит в том, чтобы разбить html на фреймы (главы) на основе тегов h1 (заголовок 1).
Цените любую помощь.
Спасибо, Сунил.
Если вы хотите получить и обработать все элементы между двумя последовательными тегами h1
, вы можете работать с родственными элементами. Вот пример кода:
public static void h1s() {
String html = "<html>" +
"<head></head>" +
"<body>" +
" <h1>title 1</h1>" +
" <p>hello 1</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>1</td>" +
" </tr>" +
" </table>" +
" <h1>title 2</h1>" +
" <p>hello 2</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>2</td>" +
" </tr>" +
" </table>" +
" <h1>title 3</h1>" +
" <p>hello 3</p>" +
" <table>" +
" <tr>" +
" <td>hello</td>" +
" <td>world</td>" +
" <td>3</td>" +
" </tr>" +
" </table>" +
"</body>" +
"</html>";
Document doc = Jsoup.parse(html);
Element firstH1 = doc.select("h1").first();
Elements siblings = firstH1.siblingElements();
List<Element> elementsBetween = new ArrayList<Element>();
for (int i = 1; i < siblings.size(); i++) {
Element sibling = siblings.get(i);
if (! "h1".equals(sibling.tagName()))
elementsBetween.add(sibling);
else {
processElementsBetween(elementsBetween);
elementsBetween.clear();
}
}
if (! elementsBetween.isEmpty())
processElementsBetween(elementsBetween);
}
private static void processElementsBetween(
List<Element> elementsBetween) {
System.out.println("---");
for (Element element : elementsBetween) {
System.out.println(element);
}
}
sibling.ownText()
перед вызовом processElementsBetween(elementsBetween);
. Я не уверен, что вы имеете в виду, говоря, чтобы заголовки шли по порядку. Документация JSoup: поваренная книга и apidocs
- person MarcoS; 14.07.2011
<h1/>this<h1/>
. Кажется, это дыра в концепции jsoup.
- person Jarekczek; 23.04.2012
Я не очень хорошо знаю Jsoup, но прямой подход может выглядеть так:
public class Test {
public static void main(String[] args){
Document document = Jsoup.parse("<html><body>" +
"<h1>First</h1><p>text text text</p>" +
"<h1>Second</h1>more text" +
"</body></html>");
List<List<Node>> articles = new ArrayList<List<Node>>();
List<Node> currentArticle = null;
for(Node node : document.getElementsByTag("body").get(0).childNodes()){
if(node.outerHtml().startsWith("<h1>")){
currentArticle = new ArrayList<Node>();
articles.add(currentArticle);
}
currentArticle.add(node);
}
for(List<Node> article : articles){
for(Node node : article){
System.out.println(node);
}
System.out.println("------- new page ---------");
}
}
}
Знаете ли вы структуру статей и всегда ли она одинакова? Что вы хотите сделать со статьями? Рассматривали ли вы их разделение на стороне клиента? Это была бы простая работа jQuery.
Перебор элементов между последовательными элементами <h>
выглядит нормально, за исключением одного. Текст, не принадлежащий ни одному тегу, как в <h1/>this<h1/>
. Чтобы обойти это, я реализовал функцию splitElemText
для получения этого текста. Сначала разделите весь родительский элемент, используя этот метод. Затем, кроме элемента, обработайте подходящую запись из разделенного текста. Удалите вызовы htmlToText
, если вам нужен необработанный HTML.
/** Splits the text of the element <code>elem</code> by the children
* tags.
* @return An array of size <code>c+1</code>, where <copde>c</code>
* is the number of child elements.
* <p>Text after <code>n</code>th element is found in <code>[n+1]</code>.
*/
public static String[] splitElemText(Element elem)
{
int c = elem.children().size();
String as[] = new String[c + 1];
String sAll = elem.html();
int iBeg = 0;
int iChild = 0;
for (Element ch : elem.children()) {
String sChild = ch.outerHtml();
int iEnd = sAll.indexOf(sChild, iBeg);
if (iEnd < 0) { throw new RuntimeException("Tag " + sChild
+" not found in its parent: " + sAll);
}
as[iChild] = htmlToText(sAll.substring(iBeg, iEnd));
iBeg = iEnd + sChild.length();
iChild += 1;
}
as[iChild] = htmlToText(sAll.substring(iBeg));
assert(iChild == c);
return as;
}
public static String htmlToText(String sHtml)
{
Document doc = Jsoup.parse(sHtml);
return doc.text();
}