2015-01-20 40 views
0

我有我需要使用JSoup解析(我的語言是Java)完全相同的結構的HTML列表。這裏有一個例子:使用JSoup解析HTML列表創建樹結構

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

由於該數據基本上是一個樹的數據結構,我希望能夠分析它,並創建一個從數據的樹。我在使用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 
    } 
} 

產生如下的結果,它顯示它不是「走」或「穿越」了,而是不斷從文檔中選擇同樣的事情:

enter image description here

什麼是將遍歷此列表並將其放置在樹結構中的代碼是什麼?

+0

遍歷DOM的問題是什麼? – RealSkeptic 2015-01-20 18:59:56

+0

我認爲問題在於我,我不知道如何正確使用JSoup來遍歷DOM。基本上問題是調用的結果像'Element list = doc.select(「ul」)。first();',如果我再次對結果調用相同的代碼'Element subList = list.select(「ul 「).first();',我得到了與第一次調用相同的結果。我想我期望圖書館只「消費」選定的部分。不知道這是否有道理。 – Monochrome 2015-01-20 19:10:53

回答

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將是你的樹結構節點的這點是要告訴你,你必須遍歷。 children。如果你喜歡,你可以在同一個循環中處理li元素)

+0

謝謝你的回答,簡單而有幫助。 – Monochrome 2015-01-23 17:31:10

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。

+0

感謝您的答案,但這並不按預期工作(這是我的問題的來源)。我添加了上面的截圖和示例,您可以使用它來闡明。 – Monochrome 2015-01-20 19:35:47