Добрый день!
Как можно пропарсить HTML теги, принимая в расчет, что к каждому открытому тегу соответствует закрытый?
Это была задача.
Дан HTML файл, необходимо в этом файле найти все строки соответствующие заданному тегу.
Строчки в теге могут содержать вложенные теги.
Например, искомый тег
на входе
<span xml:lang="en" lang="en">Текст текст <b><span>Имя Фамилия</span></b></span>
на выходе
<span xml:lang="en" lang="en">Текст текст <b><span>Имя Фамилия</span></b></span>
<span>Имя Фамилия</span>
Я понимаю, что есть раззличные парсеры и библиотеки, но хотелось бы самому понять как это работает. Какие есть алгоритмы и как работают.
У меня есть мое решение. Оно рабочее, но чувствую, что можно сделать лучше и аккуратней.
public static void main(String[] args) throws Exception {
String tagName = args[0]; // входящий тэг
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String filename = reader.readLine();
reader.close();
StringBuilder sb = new StringBuilder();
//считал из файла все строки и перевел в одну строку
BufferedReader br = new BufferedReader(new FileReader(filename));
String data = br.readLine();
while (data != null) {
sb.append(data);
data = br.readLine();
}
br.close();
String fileData = sb.toString(); // итоговая строка для поиска в ней
int n = fileData.indexOf(tagName);
int flag = 0;
ArrayList<Integer> forIndex = new ArrayList<>();
while (n != -1) { //если нет тегов, то indexOf return -1
String tag = fileData.substring(n-1, n + tagName.length());
if (("<" + tagName).equals(tag)) { //если нашли открывающий тэг
flag++;
forIndex.add(n - 1);
}
else if (("/" + tagName).equals(tag)) { //если нашли закрывающий тэг
flag--;
forIndex.add(n + tagName.length() + 1);
}
if (flag == 0) { // когда закрыли открытый тэг
while (forIndex.size() > 0) { //из списка индексов собрали индексы "по краям и вглубь"
int start = forIndex.remove(0);
int end = forIndex.remove(forIndex.size() - 1);
System.out.println(fileData.substring(start, end));
}
}
n = fileData.indexOf(tagName, n + tagName.length());
}
}
Прошу вашей помощи в данном вопросе.
P.S. мне думается, что данные методики можно применять и при парсинге различных скобок, других тегов (XML) и подобном. Полезные знания могли бы получиться.