Jsoup解析和嵌套标签

时间:2012-03-24 17:31:10

标签: java jsoup

我正在学习Jsoup并拥有这个HTML:

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

我使用Jsoup.parse()和文档select(“p”)来捕获“内容”(并且效果很好)。但...

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

在这个场景中,我看到Jsoup.parse()将此代码转换为:

 [...]
 <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>
 [...]

如何使用Jsoup(div 3中的div 4&amp; 5)保持嵌套段落的顺序?


添加示例:

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>

Java代码

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

返回

<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>

这是正确的吗?我使用Jsoup 1.6.1。我知道Jsoup应该返回嵌套段落而不是之前的返回。

2 个答案:

答案 0 :(得分:3)

HTML中不存在嵌套段落。自Jsoup implements the WHATWG HTML5 specification以来,前一段自动关闭:

  1. p代码会自动由以下任意标记关闭:addressarticleasideblockquotediv,{ {1}},dlfieldsetfooterformh1h2h3,{{1 }},h4h5h6headerhgrouphrmainmenunavolppresection。因此table
  2. 名称为ul(即<p><div></div> becomes <p></p><div></div>)且没有相应开始标记的结束标记是解析错误,并替换为p。因此</p>变为<p>
  3. 所以jsoup是正确的,你的HTML无效。

    请务必理解您的HTML无效,因为您有太多<span></span></p>而不是因为“嵌套”段落。嵌套不能发生,因为它们会自动关闭。但是后来的<span></span><p>是obsolet,因为“对应的”</p>之前已经自动关闭。

答案 1 :(得分:0)

Hj,我理解原来的问题。但我认为这是Jsoup(不是你的)的错误。由于这是一个简单的例子:

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

但是Jsoup解析了这个:

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

如果可以,请提交此错误,以便作者可以解决: - )

P.S:只是一个单词“hi”,stackoverflow不允许它?