Что ж, я попал на эту страницу сегодня, пытаясь сделать очень похожую вещь, и я верю, что решил ее. Надеюсь, кто-то все еще смотрит это сейчас, через месяц. ;)
То, что я нашел, работало хорошо, вместо того, чтобы выполнять замену строк и повторный анализ документа в каждом цикле, перестраивать содержимое элемента style
. Одним из мест, где JSoup действительно блестит, является то, как легко его API упрощает редактирование разобранного документа.
Другой трюк заключается в использовании функции data()
. JSoup различает данные (например, script
и style
) и узлы html / text. Основное отличие состоит в том, что экранирование HTML не применяется к узлам данных.
Собрав все это вместе, следующий фрагмент кода должен заменить ссылки на импортированные таблицы стилей на текст FOUND
, но без изменения форматирования документа:
// compile the regex before entering the loop, as it's a relatively expensive operation
Pattern pattern = Pattern.compile("url\\(\"(.)*\"\\)");
for(Element styleElem : doc.getElementsByTag("style")) {
String data = styleElem.data();
StringBuffer newData = new StringBuffer();
Matcher matcher = pattern.matcher(data);
while(matcher.find()) {
matcher.appendReplacement(newData, "FOUND");
}
matcher.appendTail(newData);
styleElem.appendChild(new DataNode(newData.toString(), base.toExternalForm()));
}
P.S. Я предполагаю, что вы отключили симпатичную печать. Поскольку ваш код синтаксического анализа документа не отображается, дважды убедитесь, что после синтаксического анализа вызвала document.outputSettings().prettyPrint(false);
.
P.P.S. В моем собственном коде я использую более терпимое (и немного более уродливое) регулярное выражение для поиска импорта. Это позволяет пользователю избегать пропуска декларации URL, кавычек, паренов и т. Д., Потому что дикий HTML имеет тенденцию делать все эти вещи. Я объявил это в моем коде следующим образом:
public static final Pattern CSS_IMPORT_PATTERN = Pattern.compile("(@import\\s+(?:url)?\\s*\\(?\\s*['\"]?)(.*?)([\\s'\";,)]|$)");