Jsoup代码解读之五-parser(中)

代码结构

先介绍以下parser包里的主要类:

  • Parser

Jsoup parser的入口facade,封装了常用的parse静态方法。可以设置maxErrors,用于收集错误记录,默认是0,即不收集。与之相关的类有ParseError,ParseErrorList。基于这个功能,我写了一个PageErrorChecker来对页面做语法检查,并输出语法错误。

  • Token

保存单个的词法分析结果。Token是一个抽象类,它的实现有Doctype,StartTag,EndTag,Comment,Character,EOF6种,对应6种词法类型。

  • Tokeniser

保存词法分析过程的状态及结果。比较重要的两个字段是state和emitPending,前者保存状态,后者保存输出。其次还有tagPending/doctypePending/commentPending,保存还没有填充完整的Token。

  • CharacterReader

对读取字符的逻辑的封装,用于Tokenize时候的字符输入。CharacterReader包含了类似NIO里ByteBuffer的consume()、unconsume()、mark()、rewindToMark(),还有高级的consumeTo()这样的用法。

  • TokeniserState

用枚举实现的词法分析状态机。

  • HtmlTreeBuilder

语法分析,通过token构建DOM树的类。

  • HtmlTreeBuilderState

语法分析状态机。

  • TokenQueue

虽然披了个Token的马甲,其实是在query的时候用到,留到select部分再讲。

词法分析状态机

现在我们来讲讲HTML的词法分析过程。这里借用一下http://ued.ctrip.com/blog/?p=3295里的图,图中描述了一个Tag标签的状态转移过程,

这里忽略了HTML注释、实体以及属性,只保留基本的开始/结束标签,例如下面的HTML:

<div>test</div>

Jsoup里词法分析比较复杂,我从里面抽取出了对应的部分,就成了我们的miniSoupLexer(这里省略了部分代码,完整代码可以看这里MiniSoupTokeniserState):

参考这个程序,可以看到Jsoup的词法分析的大致思路。分析器本身的编写是比较繁琐的过程,涉及属性值(区分单双引号)、DocType、注释、HTML实体,以及一些错误情况。不过了解了其思路,代码实现也是按部就班的过程。

原文发布于微信公众号 - java一日一条(mjx_java)

原文发表时间:2016-05-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

linux运维中的命令梳理(三)

----------文本操作命令---------- sed命令:文本编辑工具 sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可...

2408
来自专栏Android中高级开发

Android并发编程 多线程与锁

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的。

1812
来自专栏程序你好

Java虚拟机JVM架构解析

每个Java开发人员都知道字节码将由JRE (Java运行时环境)运行。但是许多人不知道JRE是Java虚拟机(JVM)的实现,它分析字节码、解释并执行代码。作...

702
来自专栏Janti

Java多线程高并发学习笔记(二)——深入理解ReentrantLock与Condition

锁的概念 从jdk发行1.5版本之后,在原来synchronize的基础上,增加了重入锁ReentrantLock。 本文就不介绍synchronize了,有兴...

4206
来自专栏北京马哥教育

ansible之playbook功能简述

playbooks剧本简介 playbooks是ansible更为强大的配置管理组件,实现基于文本文件编排执行的多个任务,且多次重复执行。其是使用YAML(Ye...

3465
来自专栏开源优测

BeautifulSoup的使用

参考资料地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#id28

1201
来自专栏lgp20151222

$.ajax()方法参数详解

type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器...

721
来自专栏QQ音乐技术团队的专栏

一种Android App在Native层动态加载so库的方案

这篇文章通过实战案例,介绍了一种有条理的组织Native层代码层级结构的方法。并且,在良好的代码层级、作用分工的基础上,实现了动态的按需加载、卸载so库。文章...

1K6
来自专栏张首富-小白的成长历程

Linux-四剑客-find-awk-grep-sed解释----未完结版

find - search for files in a directory hierarchy 搜索目录层次结构中的文件 用来在指定目录下面查找文件或目录,任...

1313
来自专栏Android中高级开发

Android并发编程 多线程与锁

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的。

1066

扫码关注云+社区