HTMLParser使用visitor访问html dom树节点的原理
来源:互联网 发布:php分页代码实例 编辑:程序博客网 时间:2024/06/14 08:58
上一篇讲解了filter访问html树的原理,今天在讲解一下htmlparser中visitor访问html的dom树的原理。网上关于htmlparser工作原理的资料比较少,要想学习htmlparser最好看htmlparser的源码,htmlparser源码不算大,代码都是大牛们写的,可读性非常好,只要从main函数中跟踪程序的执行过程就能够很好的了解htmlparser的工作原理。下面总结一下我关于htmlparser的visitor访问机制的一些理解。
和上一篇《HTMLParser使用Filter遍历html DOM树的原理》使用的html源码一样,如下所示:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>白泽居-www.baizeju.com</title></head> <body > <div id="top_main" class="name"> <div id="logoindex"> 白泽居-www.baizeju.com<a href="http://www.baizeju.com">白泽居-www.baizeju.com</a> </div> <div class="name">东方教主文成武德,一同江湖</div> </div> </body> </html>
他被组织成三棵树的森林,其中以<html>标签为根节点的树高度最大,网页的树状结构图如下:
下面我们就跟踪代码来发现visitor机制的工作原理:
(1)首先是main函数,我们使用htmlparser中自带的LinkFindingVisitor进行试验(htmlparser中自带的Visitor类不能满足我们的需求,他们存在的目的是让我们能够了解Visitor访问机制的工作原理,如果我们要实现自己的功能需要写自己的Visitor子类),下面是main函数的代码,功能很简单就是统计源码中存在某类链接的个数。
package parsertool;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.FileInputStream;import java.io.File;import java.net.HttpURLConnection;import java.net.URL;import org.htmlparser.Node;import org.htmlparser.filters.TagNameFilter;import org.htmlparser.util.NodeIterator;import org.htmlparser.util.NodeList;import org.htmlparser.visitors.LinkFindingVisitor;import org.htmlparser.Parser;public class Nodes { public static void main(String[] args) { try{ Parser parser = new Parser("http://211.87.234.91:8088/SearchEngine/mypage.html" ); LinkFindingVisitor visitor = new LinkFindingVisitor("xiao"); parser.visitAllNodesWith(visitor); System.out.println("count=="+visitor.getCount()); System.out.println("finished.............................."); } catch( Exception e ) { System.out.println( "Exception:"+e ); } }
(2)然后跟踪Parser的visitAllNodesWith()类,他的参数是LinkFindingVisitor实例,他的代码如下所示:
public void visitAllNodesWith (NodeVisitor visitor) throws ParserException { Node node; visitor.beginParsing(); for (NodeIterator e = elements(); e.hasMoreNodes(); ) { node = e.nextNode(); node.accept(visitor); } visitor.finishedParsing(); }
解释:for循环中对html源码形成的森林中的每个树根节点进行遍历,调用每个节点的accept方法,htmlparser将所有的html节点分成了四大类(TagNode,CompositeTag,TextNode和RemarkNode)。CompositeTag相当于中间节点,他有自己的子节点,其他三种节点都是叶节点,没有子节点。
(3)四种节点的accept方法负责完成dom树的遍历工作,因为CompositeTag有子节点,所有他除了需要遍历自身以外还需要遍历递归遍历他的所有子节点(但是Visitor有两个参数mRecurseChildren,mRecurseSelf可以指定是否需要遍历自身和是否需要遍历子节点);其他三种节点没有叶节点他们只需要调用参数Visitor对应的方法访问本身就行了,相对比较简单,下面我们重点介绍一下CompositeTag的accept方法:
public void accept (NodeVisitor visitor) { SimpleNodeIterator children; Node child; if (visitor.shouldRecurseSelf ()) visitor.visitTag (this); if (visitor.shouldRecurseChildren ()) { if (null != getChildren ()) { children = children (); while (children.hasMoreNodes ()) { child = children.nextNode (); child.accept (visitor); } } if ((null != getEndTag ()) && (this != getEndTag ())) // 2nd guard handles <tag/> getEndTag ().accept (visitor); } }
htmlparser中的visitor访问机制和filter机制都能实现我们想要的功能,都是以html树状结构的遍历为基础的,所以理解好dom树对应用程序开发是十分关键的,还有就是htmlparser的源码相对比较小,而且调理清晰,通过源码的学习应该可以很好的理解htmlparser工作原理。
- HTMLParser使用visitor访问html dom树节点的原理
- HTMLParser使用Filter遍历html DOM树的原理
- HTMLParser的visitor访问方式详解
- HTMLParser使用详解(4)- 通过Visitor访问内容
- HTMLParser使用详解(4)- 通过Visitor访问内容
- HTMLParser使用详解(4)- 通过Visitor访问内容
- HTMLParser使用详解(4)- 通过Visitor访问内容
- HTMLParser使用详解(4)- 通过Visitor访问内容
- HTMLParser使用详解(4):通过VISITOR访问内容
- HTMLParser使用详解(4) - 通过Visitor访问内容
- HTMLParser使用详解(4)- 通过Visitor访问内容
- 通过 DOM访问 HTML 文档中的节点
- 利用DOM节点关系访问HTML元素
- HtmlParser visitor
- 访问受控的dom节点
- Dom 节点的属性访问
- 使用Python的HTMLParser解析HTML文本
- 使用HtmlParser解析HTML
- SQLServer2008 字符串函数一览表(转)
- Django笔记——Eclipse+pydev首个django例子helloworld
- android中requestFocus
- Hibernate三种状态(Transient、Persistent、Detached)各种保存(save,persist,update,saveOrUpdte,merge,flush,lock)区别
- Java加密技术
- HTMLParser使用visitor访问html dom树节点的原理
- SharePoint 2010 Download as Zip File Custom Ribbon Action
- windows上搭建apache+mysql+django的过程
- 现在就开始使用AngularJS
- 线程的取消/撤销(cancel)【】
- 传话游戏
- html页面元素onclick 和 jquery绑定click执行顺序
- 遇到的问题-在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误
- 数据结构学习笔记(二)各种排序