Удаление родительских тегов без удаления потомков с помощью Jsoup - PullRequest
1 голос
/ 10 апреля 2020

Пример кода для переделки:

       <div class="mrd3w m6et0 _2d49e_1O4vF"> 
        <div class="p1td4 pw4go p513t al2kje m10qy mij5n"> 
         <div class="_2d49e_2tor6" style="max-width:871px;max-height:552px"> 
          <div class="ptv8j2" style="padding-top:calc(100% * 552 / 871)">
           <img alt="alt" class="_2d49e_3B1Cq pt94f9 pt1itw ptux49 w1eai _2d49e_32cUf lazyloaded" sizes="(min-width: 1200px) 560px, (min-width: 992px) 50vw, 100vw" src="https://somelink.com 871w" width="871px">
          </div> 
         </div> 
        </div> 
       </div> 

Я уже удалил некоторые бесполезные ссылки и импортировал из этого html, и это моя последняя проблема. Классы div являются случайными и их много.

Мне нужно получить простой чистый код, подобный следующему:

<div>
  <img alt="alt" src="https://somelink.com">
</div>

Я создаю файл xml из базы данных, и описание каждого продукта - это беспорядок, который должен быть таким же чистым, как возможный. Все описание находится в базе данных как значение со всеми этими беспорядками iports и тегами. Я использую Jsoup для переделки этого описания, но понятия не имею, как удалить родителей, не удаляя детей.

1 Ответ

1 голос
/ 11 апреля 2020

Для этого требуется два шага:

  1. Для очистки нежелательных тегов и атрибутов используйте Whitelist и Jsoup.clean(html, whitelist)
  2. Для удаления родителя вы можете использовать element.unwrap(). Чтобы удалить повторяющихся родителей, мы можем перейти вверх, используя al oop, и удалить их, если они одинаковые.

Вот код, который делает это:

public class JsoupIssue61137870 {

    public static void main(final String[] args) throws IOException {
        String html = "  <div class=\"mrd3w m6et0 _2d49e_1O4vF\"> \n"
                + "        <div class=\"p1td4 pw4go p513t al2kje m10qy mij5n\"> \n"
                + "         <div class=\"_2d49e_2tor6\" style=\"max-width:871px;max-height:552px\"> \n"
                + "          <div class=\"ptv8j2\" style=\"padding-top:calc(100% * 552 / 871)\">\n"
                + "           <img alt=\"alt\" class=\"_2d49e_3B1Cq pt94f9 pt1itw ptux49 w1eai _2d49e_32cUf lazyloaded\" sizes=\"(min-width: 1200px) 560px, (min-width: 992px) 50vw, 100vw\" src=\"https://somelink.com 871w\" width=\"871px\">\n"
                + "          </div> \n" + "         </div> \n" + "        </div> \n" + "       </div> ";

        Whitelist whitelist = Whitelist.none();
        whitelist.addTags("div", "img");
        whitelist.addAttributes("img", "src");
        String cleanHTML = Jsoup.clean(html, whitelist);
        System.out.println(cleanHTML);

        String result = removeRepeatingTags(cleanHTML);
        System.out.println(result);
    }

    private static String removeRepeatingTags(String html) {
        Document doc = Jsoup.parse(html);
        Element img = doc.selectFirst("img");
        Element parent = img.parent();
        while (parent.tagName().equals(parent.parent().tagName())) {
            parent.unwrap();
            parent = img.parent();
        }
        return doc.toString();
    }
}

Выход из первая часть:

<div> 
 <div> 
  <div> 
   <div> 
    <img alt="alt" src="https://somelink.com 871w"> 
   </div> 
  </div> 
 </div> 
</div>

и вывод после второй части:

<html>
 <head></head>
 <body>
  <div>    
    <img alt="alt" src="https://somelink.com 871w">  
  </div>
 </body>
</html>

Jsoup добавит теги <html> <head> и <body>. Чтобы избежать этого, вместо

    Document doc = Jsoup.parse(html);

используйте

    Document doc = Jsoup.parse(html, "", Parser.xmlParser());

, и результат будет точно таким, как вы ожидаете:

<div>    
 <img alt="alt" src="https://somelink.com 871w">    
</div>
...