3 votes

Parse de Jsoup et balises imbriquées

Je suis en train d'apprendre Jsoup et j'ai ce HTML :

 [...]
 <p style="..."> <!-- div 1 -->
   Content
 </p>
 <p style="..."> <!-- div 2 -->
   Content
 </p>
 <p style="..."> <!-- div 3 -->
   Content
 </p>
 [...]

J'utilise Jsoup.parse() et document select("p") pour attraper le "contenu" (et ça marche bien). Mais...

 [...]
 <p style="..."> <!-- div 1 -->
   Content
 </p>
 <p style="..."> <!-- div 2 -->
   Content
 </p>
 <p style="..."> <!-- div 3 -->
   Content
   <p style="..."></p>
   <p style="..."></p>
 </p>
 [...]

Dans cette scène, je vois que Jsoup.parse() convertit ce code en :

 [...]
 <p style="..."> <!-- div 1 -->
   Content
 </p>
 <p style="..."> <!-- div 2 -->
   Content
 </p>
 <p style="..."> <!-- div 3 -->
   Content
 </p>
 <p style="..."> <!-- div 4 -->
 </p>
 <p style="..."> <!-- div 5 -->
 </p>
 [...]

Comment conserver l'ordre des paragraphes imbriqués avec Jsoup (div 4 & 5 à l'intérieur de div 3) ?


Ajoutez un exemple :

Fichier HTML :

 <html>
 <head>
    <title>Title</title>
 </head>
 <body>
    <p style="margin-left:2em">
            <span class="one">Text</span>
            <span class="two"><span class="nest">Text</span></span>
            <span class="three"></span>
    </p>
    <p style="margin-left:2em">
            <span class="one">Text</span>
            <span class="two"><span class="nest">Text</span></span>
            <span class="three"></span>
    </p>
    <p style="margin-left:2em">
            <span class="one">Text</span>
            <span class="two"><span class="nest">Text</span></span>
            <span class="three"></span>
            <p style="margin-left:2em"></p>
            <p style="margin-left:2em"></p>
    </p>

 </body>
 </html>

Code Java :

Document doc = null;
doc = Jsoup.connect(URL_with_HTML).get();
System.out.println(doc.outerHtml());

Retourner à :

<html>
<head> 
 <title>Title</title> 
</head> 
<body> 
 <p style="margin-left:2em"> <span class="one">Text</span> <span class="two"><span class="nest">Text</span></span> <span class="three"></span> </p> 
 <p style="margin-left:2em"> <span class="one">Text</span> <span class="two"><span class="nest">Text</span></span> <span class="three"></span> </p> 
 <p style="margin-left:2em"> <span class="one">Text</span> <span class="two"><span class="nest">Text</span></span> <span class="three"></span> </p>
 <p style="margin-left:2em"></p> 
 <p style="margin-left:2em"></p> 
 <p></p>   
</body>
</html>

Est-ce correct ? J'utilise Jsoup 1.6.1. Je comprends que Jsoup devrait retourner les paragraphes imbriqués au lieu du retour précédent.

3voto

Fabian Barney Points 5707

Les paragraphes imbriqués n'existent pas en HTML. Le paragraphe précédent est fermé automatiquement puisque Jsoup met en œuvre la spécification WHATWG HTML5 :

  1. A p est automatiquement fermée par l'un des éléments suivants : address , article , aside , blockquote , div , dl , fieldset , footer , form , h1 , h2 , h3 , h4 , h5 , h6 , header , hgroup , hr , main , menu , nav , ol , p , pre , section , table o ul . Par conséquent, <p><div></div> becomes <p></p><div></div> .
  2. Une balise de fin dont le nom est p (ie </p> ) qui n'a pas de balise de début correspondante est une erreur d'analyse et est remplacé par <p> . Par conséquent, <span></span></p> devient <span></span><p> .

Donc jsoup est correct et votre HTML est invalide.

Assurez-vous de comprendre que votre HTML n'est pas valide parce que vous avez trop de </p> et non parce que les paragraphes "nesting". L'imbrication ne peut pas se produire parce qu'ils sont fermés automatiquement. Mais l'arrivée ultérieure </p> est obsolète car le "correspondant" <p> a déjà été fermée automatiquement auparavant.

0voto

Hj, je comprends la question initiale. Mais je pense que c'est un bug de Jsoup (pas le vôtre). Puisque c'est un exemple simple :

<html>
    <head></head>
    <body>
        <p></p>
        <p>
            <div></div>
        </p>
    </body>
</html>

Mais Jsoup analyse cela :

<html>
    <head></head>
    <body>
        <p></p>
        <p></p>
        <div></div>
        <p></p>
    </body>
</html>

Si vous le pouvez, veuillez signaler ce bogue afin que l'auteur puisse le corriger :-)

P.S : Juste un mot "salut", stackoverflow ne le permet pas ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X