【问题标题】:How to update an Elements so that it does not contain Removed Links?如何更新元素以使其不包含已删除的链接?
【发布时间】:2016-08-12 04:26:12
【问题描述】:

注意:有一个类似的问题被问到HERE。但是,我已经审查了这个问题,它并没有解决我的问题。请提前阅读。

我编写了一个尝试从Elements 中删除某些链接的方法。我知道remove() 会从它所在的Document ob 中删除Element。但是,如何更新我的 Elements 使其不包含已删除的链接?

下面是我的方法。

public void getLinks(Document site) {

    Elements links = site.select("a[href]");

    for(int i = 0 ; i < links.size() ; i++) {

      String url = links.get(i).attr("abs:href");

      if(url.endsWith("~S1")) {
        System.out.println(url);
      } else {
        links.remove(i); // links still contains removed Element
      }
    }
}

【问题讨论】:

  • 当心!事实上,循环:for (int i = 0; i &lt; 0; i++),永远不会发生,因为i &lt; 0 在开始循环之前返回false ...
  • 你既不能使用 i0 ,如果你使用 i>0 你将有一个无限循环。而不是 0 使用另一个整数值。因为你不能在for循环中反复检查起始值的条件。
  • 感谢您的指点 :) 但是,我的问题仍然存在。还有其他想法吗?

标签: java jsoup


【解决方案1】:

我建议你使用listIterator。 您可以在遍历列表时安全地删除元素(元素扩展了 ArrayList 类)

 ListIterator<Element> it = links.listIterator();
 while(it.hasNext()){
   Element link = it.next();
   String url = links.get(i).attr("abs:href");
   if(... {// your condition. I can't properly copy, writing from a mobile phone
   link.remove();
   }
 }

请记住,在使用常见的for 运算符进行迭代时,从列表中删除元素是不安全的。因为重新索引。例如。你已经删除了第 5 个元素,循环计数器增加了 1,你想要删除第 6 个元素,而是删除第 7 个元素。列表接口不保留空索引,因此它会在删除操作后立即重新组织元素列表,有利于保持不可破坏的序列。
用于您的任务ListIterator power,它是为删除、双向迭代等目的而创建的。

【讨论】:

    【解决方案2】:

    如何更新我的元素,使其不包含已删除的链接?

    Elements 实际上提供了几种方便的方法,不需要为此迭代或循环遍历子元素。

    起始html:

    <html>
     <head></head>
     <body>
      <div> 
       <a href="foo.html?S1">foo</a> 
       <a href="not_foo.html">not foo</a> 
       <a href="foo2.html?S1">foo2</a> 
      </div>
     </body>
    </html>
    

    获取样本Elementsobj:

    Elements elements = doc.select("a");
    
    System.out.println(elements.outerHTML());
    
    ...
    
    <a href="foo.html?S1">foo</a>
    <a href="not_foo.html">not foo</a>
    <a href="foo2.html?S1">foo2</a>
    

    要从Elements 对象中删除以“S1”结尾的链接:

    elements.removeAll(elements.select("a[href$=S1]"));
    
    System.out.println(elements.outerHTML());
    
    ...
    
    <a href="not_foo.html">not foo</a>
    

    或者,创建一个不包含以“S1”结尾的链接的新Elements obj:

    Elements cleanLinks = elements.not("a[href$=S1]");
    
    System.out.println(cleanLinks.outerHtml());
    
    ...
    
    <a href="not_foo.html">not foo</a>
    

    注意:Elements.remove(Collection)Elements.not(String) 都不会从 Document 对象中删除元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2012-08-23
      • 2014-08-28
      相关资源
      最近更新 更多