Apache Tika-內容解析提取工具集合
簡介
Apache Tika toolkit可以自動檢測各種文檔(如word,ppt,xml,csv,ppt等)的類型并抽取文檔的元數據和文本內容。Tika集成了現有的文檔解析庫,并提供統一的接口,使針對不同類型的文檔進行解析變得更簡單。Tika針對搜索引擎索引、內容分析、轉化等非常有用。
支持的文檔格式
詳見參見http://tika.apache.org/1.5/formats.html
- HyperText Markup Language
- XML and derived formats
- Microsoft Office document formats
- OpenDocument Format
- Portable Document Format
- Electronic Publication Format
- Rich Text Format
- Compression and packaging formats
- Text formats
- Feed and Syndication formats
- Audio formats
- Image formats
- Video formats
- Java class files and archives
- The mbox format
- CAD formats
- Font formats
- Executable programs and libraries
處理過程
Tika通過一個parser和一個contentHandler來進行文檔分析和處理,其中parser負責解析具體的文檔,當解析到需要進行處理的時候,調用contentHandler進行解析內容的處理。contentHandler(org.xml.sax)是一個用于處理sax解析的程序接口,當parser解析到某些內容時(如節點之間的信息,以及節點本身的信息)時,便會根據需要去調用contentHandler的相關處理方法。即一個負責解析,一個負責處理,兩者相互協作,最終將信息通過一定的手段返回回來。
Parser是一個接口,對不同的文檔進行處理時,需要尋找具體的解析器來實現具體的解析工作。Tika通過MimeType來實現對一個文檔的具體識別工作,即識別出一個文檔是什么樣的類型,然后再根據類型尋找相應的parser。最后調用具體實現的parser來完成parse工作。
ContentHandler也是一個接口,對不同的信息進行處理時,需要自己調用具體的信息處理類。一般來說,如果只關心文檔內的內容(即有信息的地方),可以使用WriteOutContentHandler。這個handler將所以被解析到的信息通過一個output或write輸出到調用者提供的輸出流中,這樣最終可以讀取這個writer中的數據。
除這些信息之外,還有一些信息需要在處理的過程中被解析和保存,比如一個文檔的標題,作者以及contentType等。在tika中,這些信息被保存在一個叫Metadata的對象中。metadata保存了很多與具體文檔相關的值,它以一個map的形式,保存相應的元數據信息值。如對于word,它會保存其中的Author,Keywords這些信息。這些信息對于用一些關鍵信息進行文檔檢索非常有用。
主要接口
org.apache.tika.parser.Parser
/*
*
* 解析一個文件流成一個序列的XHTML SAX事件
*
* 在指定的metadata對象中填充文檔相關的元數據信息
*
* 解析后不會關閉文檔流,關閉文檔流由調用者負責
*
* @param stream the document stream (input)
* @param handler handler for the XHTML SAX events (output)
* @param metadata document metadata (input and output)
* @param context parse context
* @throws IOException if the document stream could not be read
* @throws SAXException if the SAX events could not be processed
* @throws TikaException if the document could not be parsed
*/
void parse(
InputStream stream, ContentHandler handler,
Metadata metadata, ParseContext context)
throws IOException, SAXException, TikaException; org.xml.sax.ContentHandler
這是大多數SAX應用程序要實現的接口。
如果應用程序需要得到基本分析事件的通知,它需要實現這個接口,并用SAX parser注冊一個實例。
解析器使用這個實例報告文檔相關的事件如element的start,end
代碼示例
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
public class WordParserDemo {
public static final String INPATH = "E:/test.xlsx";
public static final String OUTPATH = "data.txt";
public static void main(String[] args) throws IOException, SAXException,
TikaException {
// 針對97-2003的microsoft office使用
// Parser parser = new OfficeParser();
// 針對microsoft office 2007及其以后的版本,使用
// Parser parser = new OOXMLParser();
// 或簡單的使用AutoDetectParser
parseFile(INPATH, OUTPATH);
}
public static boolean parseFile(String inFile, String outFile) {
boolean result = false;
InputStream in = null;
OutputStream out = null;
try {
//創建輸入、輸出流
in = new BufferedInputStream(new FileInputStream(new File(inFile)));
out = new BufferedOutputStream(new FileOutputStream(
new File(outFile)));
// 設置metadata
Metadata meta = new Metadata();
meta.add(Metadata.CONTENT_ENCODING, "utf-8");
meta.set(Metadata.RESOURCE_NAME_KEY, inFile);
// 設置contentHandler (可以替換為WriteOutContentHandler)
ContentHandler handler = new BodyContentHandler(out);
// 創建parser
Parser parser = new AutoDetectParser();
// 解析文檔
parser.parse(in, handler, meta, new ParseContext());
// 打印metadata信息
for (String name : meta.names()) {
System.out.println(name + ":" + meta.get(name));
}
} catch (Exception e) {
result = false;
System.out.println(e.getMessage());
} finally {
try {
if (in != null)
in.close();
if(out != null)
out.close();
} catch (IOException e1) {
System.out.println(e1.getMessage());
}
}
return result;
}
}