使用JSoup解析HTML列表以创建树结构

时间:2015-01-20 18:45:19

标签: java html jsoup

我的HTML列表与我需要使用JSoup解析的结构完全相同(我的语言是Java)。这是一个例子:

<div class="ulist">
  <ul>
    <li><p>Healthy Food</p></li>
    <div class="ulist">
      <ul>
        <li><p>Vegetables</p></li>
        <div class="ulist">
          <ul>
            <li> <p>Carrots</p> </li>
            <li> <p>Lettuce</p> </li>
            <li> <p>Cucumbers</p> </li>
          </ul>
        </div> </li>
        <li> <p>Fruits</p>
          <div class="ulist">
            <ul>
              <li> <p>Apples</p> </li>
              <li> <p>Bananas</p> </li>
              <li> <p>Canned Fruits</p></li>
              <div class="ulist">
                <ul>
                  <li> <p>Peaches</p> </li>
                  <li> <p>Pears</p> </li>
                </ul>
              </div>
            </ul>
          </div>
        </li>
      </ul>
    </div>
  </ul>
</div>

由于这些数据基本上只是一个Tree数据结构,我希望能够解析它并从数据中创建一个Tree。我在使用JSoup时遇到了困难,因为看起来你无法按预期真正遍历DOM。

例如,代码如下:

Elements elList = doc.select("ul");
for (Element el: elList){
  Elements subList = el.select("ul");
  for (Element subEl : subList){
    //do whatever you need to do
  }
}

产生以下结果,看来它不是&#34;行走&#34;或者&#34;遍历&#34;向下,而是继续从文档中选择相同的东西:

enter image description here

什么代码将遍历此列表并将其放在树结构中?

2 个答案:

答案 0 :(得分:1)

在JSoup中,select()getElementByTag()都会将当前元素作为结果的一部分返回,如果它与标记匹配。

因此,当您执行doc.select("ul")并对结果执行select()时,您将获得与您已经注意到的相同的结果。

正确执行此操作的关键是获取第一个元素,然后搜索其子元素

有些事情:

public static Node processTree( Element elem ) {

     Node result;

     Elements elList = elem.getElementsByTag("ul");

     if ( elList == null || elList.size() == 0 ) {
         return null;
     };

     result = new Node();
     Element current = elList.first();
     elList = current.children();

     // Process LI elements and add them as content to the
     // result Node
     ...

     // Now go down the tree

     if ( elList != null && elList.size() != 0 ) {

        for ( Element el : elList ) {
            Node elTree = processTree( el );
            if ( elTree != null ) {
                result.addChild( elTree );
            }
        }
     }

     return result;
}

(当然,这只是一个草图。Node将是你的树结构节点。这一点是为了告诉你必须遍历孩子。你如果你愿意,可以处理同一循环中的li个元素。

答案 1 :(得分:0)

JSoup将DOM构建为内存中的数据结构,您可以使用非常强大的“随机访问”方式访问它,例如使用优秀的css选择器实现。要使用JSoup解决您的问题,您可以循环结果如下:

Elements elList = doc.select("ul");
for (Element el: elList){
    Elements subList = el.select("ul");
    for (Element subEl : subList){
       //do whatever you need to do
    }
}

但是,如果你需要遍历非常大的html文件并且文件结构良好,你可能想要使用像SAX这样的库。这避免了将整个DOM保存在内存中。