由于我们的业务系统中有大量的MHT格式的资料,需要对其建立索引,搜索很久了一直没有找到相关解析的类库,只好自己动手丰衣足食了。已实现内容的提取以及和lucene的整合,稍后会完善编码检测及其他内容的提取,做一个完整的parser出来。
文本内容提取: 首先提取html部分的内容,解码之后使用nekoHtml提取文本内容;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<code>public</code> <code>class</code> <code>MhtDocHandler </code><code>extends</code> <code>HtmDocHandler { </code>
<code> </code>
<code> </code><code>private</code> <code>DOMFragmentParser parser = </code><code>new</code> <code>DOMFragmentParser(); </code>
<code> </code><code>public</code> <code>Document getDocument(InputStream is) </code><code>throws</code> <code>DocumentHandlerException { </code>
<code> </code><code>DocumentFragment node = </code><code>new</code> <code>HTMLDocumentImpl().createDocumentFragment(); </code>
<code> </code><code>try</code> <code>{ </code>
<code> </code><code>String mhts = IOUtils.toString(is); </code>
<code> </code><code>int</code> <code>a1 = mhts.indexOf(</code><code>"<HTML"</code><code>); </code>
<code> </code><code>int</code> <code>a2 = mhts.indexOf(</code><code>"</HTML>"</code><code>); </code>
<code> </code><code>String html = mhts.substring(a1, a2 + </code><code>8</code><code>); </code>
<code> </code><code>//在mht中文本按照QuotedPrintable格式编码 </code>
<code> </code><code>html = decodeQuotedPrintable(html, </code><code>"UTF-8"</code><code>); </code>
<code> </code><code>StringReader r = </code><code>new</code> <code>StringReader(html); </code>
<code> </code><code>parser.parse(</code><code>new</code> <code>InputSource(r), node); </code>
<code> </code><code>} </code>
<code> </code><code>catch</code> <code>(Exception e) { </code>
<code> </code><code>throw</code> <code>new</code> <code>DocumentHandlerException(</code><code>"Cannot parse MHT document: "</code><code>, e); </code>
<code> </code><code>Document doc = </code><code>new</code> <code>Document(); </code>
<code> </code><code>StringBuffer sb = </code><code>new</code> <code>StringBuffer(); </code>
<code> </code><code>getText(sb, node, </code><code>"title"</code><code>); </code>
<code> </code><code>String title = sb.toString().trim(); </code>
<code> </code><code>sb.setLength(</code><code>0</code><code>); </code>
<code> </code><code>getText(sb, node, </code><code>"body"</code><code>); </code>
<code> </code><code>String text = sb.toString().trim(); </code>
<code> </code><code>if</code> <code>(!title.equals(</code><code>""</code><code>)) { </code>
<code> </code><code>doc.add(</code><code>new</code> <code>Field(WikiDOC.DOC_TITLE, title, </code>
<code> </code><code>Field.Store.YES, Field.Index.TOKENIZED, </code>
<code> </code><code>Field.TermVector.WITH_POSITIONS_OFFSETS)); </code>
<code> </code><code>if</code> <code>(!text.equals(</code><code>""</code><code>)) { </code>
<code> </code><code>doc.add(</code><code>new</code> <code>Field(WikiDOC.DOC_CONTENT, text, </code>
<code> </code><code>Field.Store.COMPRESS, Field.Index.TOKENIZED, </code>
<code> </code><code>Field.TermVector.WITH_POSITIONS_OFFSETS)); </code>
<code> </code><code>return</code> <code>doc; </code>
<code> </code><code>} </code>
<code> </code><code>public</code> <code>static</code> <code>String decodeQuotedPrintable(String str, String encoding) { </code>
<code> </code><code>if</code> <code>(str == </code><code>null</code><code>) { </code>
<code> </code><code>return</code> <code>null</code><code>; </code>
<code> </code><code>//str = str.replaceAll("=\n", "");//?? </code>
<code> </code><code>byte</code><code>[] bytes = str.getBytes(</code><code>"US-ASCII"</code><code>); </code>
<code> </code><code>ByteArrayOutputStream buffer = </code><code>new</code> <code>ByteArrayOutputStream(); </code>
<code> </code><code>for</code> <code>(</code><code>int</code> <code>i = </code><code>0</code><code>; i < bytes.length; i++) { </code>
<code> </code><code>int</code> <code>b = bytes[i]; </code>
<code> </code><code>if</code> <code>(b == </code><code>'='</code><code>) { </code>
<code> </code><code>int</code> <code>u = Character.digit((</code><code>char</code><code>) bytes[++i], </code><code>16</code><code>); </code>
<code> </code><code>int</code> <code>l = Character.digit((</code><code>char</code><code>) bytes[++i], </code><code>16</code><code>); </code>
<code> </code><code>if</code> <code>(u == -</code><code>1</code> <code>|| l == -</code><code>1</code><code>) {</code><code>//?? </code>
<code> </code><code>continue</code><code>; </code>
<code> </code><code>} </code>
<code> </code><code>buffer.write((</code><code>char</code><code>) ((u << </code><code>4</code><code>) + l)); </code>
<code> </code><code>} </code><code>else</code> <code>{ </code>
<code> </code><code>buffer.write(b); </code>
<code> </code><code>} </code>
<code> </code><code>} </code>
<code> </code><code>return</code> <code>buffer.toString(encoding); </code>
<code> </code><code>e.printStackTrace(); </code>
<code> </code><code>return</code> <code>str; </code>
<code>}</code>
本文转自 独孤环宇 51CTO博客,原文链接:http://blog.51cto.com/snowtiger/1963087