需求
html渲染是一个相对常见的需求,在web前端做起来比较容易。Java中很多组价也支持直接填入html原始数据进行格式化渲染。但有时我们需要将html转换为格式化文本,举例来说,满足如下条件
- 反转html实体,如&
- 去除所有标签
- 除换行之外的所有格式全都去除
实现
目前市面上并没有一步实现该需求的方案,最为接近可行的方案是Jsoup:https://github.com/jhy/jsoup;它能够将html文本转换为dom树,并能提取其中文本和元素。
我们的实现逻辑如下:
1 | private fun Document.format(): String { |
我们输入如下内容
1 | <div> |
得到的输出,完全满足需求
1 | 18/47/284 |
说明
这里说明编写中的注意事项
dom结构
明白dom结构很重要,最开始我就搞错了文本本身也是一个节点
1
2
3
4
5
6
7
8
9
10<!-- 评论 -->
文本1
<div>
<div>
文本1
</div>
</div>
<p>
文本2
</p>节点结构如下
1
2
3
4
5
6
7Comment
TextNode
Element(div)
- Element(div)
- TextNode
Element(p)
- TextNode换行符的处理
不能直接在块标签后增加换行符,因为块标签会嵌套,从早造成多余的换行
取而代之的,应该看下一个兄弟元素是否是块标签或换行标签
1
2
3
4
5
6
7
8<div>
<div>
文本1
</div>
</div>
<p>
文本2
</p>如上文本肯定想要得到如下结果
1
2文本1
文本2如果按块标签换行,则会得到如下结果,显然是不正确的。
1
2
3文本1
文本2“下一个相邻元素”,jsoup中有提供nextSibling()方法进行获取
超链接的处理
超链接提供getAttr()获取href属性。
评论标签的处理
评论标签有专门的节点类型——Comment,可以直接识别以忽略。