tika in action第十一章中文

本文档介绍了如何扩展Apache Tika来处理新的文件格式,以支持自定义的媒体类型检测和解析。首先,通过自定义媒体类型配置,添加了名为“application/x-prescription+xml”的新类型,并介绍了如何创建自定义检测器来识别和解析加密的医学处方文件。然后,通过实现自定义解析器,包括一个基于XMLParser的子类,用于处理未加密的处方文件,以及一个全新的解析器用于处理加密处方文件。这些扩展可以通过服务提供者机制集成到Tika中,使得Tika能够处理这些特定格式的文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自我的学习记录!

Chapter11 tika的扩展

世界上有成千上万个文件格式,而且新的还在不断地被引入,所以说tika不可能支持所有的类型。因此虽然每一个tika版本增加对新的格式支持,也没到tika可以对你正在试图使用的文件抽取内容或检测类型的时候。这一章节是关于你应该如何去处理这一情形。

想象你正在处理一种基于XML新的医学处方文件格式。每一个文件描述单一的处方,由一系列混合与自由形式的信息组成。可为了更好的安全性与隐私,处方文件能随意地数字签名和加密。11.1节说明了在实际中如何去使用数字处方文件。

将这些基于自由形式和选定某些元数据(像病人名字,标识符)的文件进行搜索是有用的。最简单的实现这样一个搜索引擎的方法是使用一个已存在的搜索栈,然后去做所需要的是去教tika如何去解析这些文件。

我们将会使用这样的数字处方文件作为扩展tika的例子。首先,我们将教会tika如何去检测和识别这类文件,然后去怎么让tika正确地解析文件。

11.1增加类型的信息

       处理一种新的文件类型的第一步是在媒体类型中识别它。我们实验性的命名处方文件格式为“application/x-prescription+xml”。前缀的“x-”表示未被官方注册的实验性类型,后缀的“+xml”是说明这是基于xml的类型。

       我们也需要一些信息去帮助处方文件的自动检测。正如在第四章讨论的,文件扩展名和XML根元素是类型检测的很好提示。所以,我们假定处方文件被命名”.xpd”作为处方文件扩展名。进一步的,我们假定XML文件以一个”<xpd:prescription>”元素开始,其前缀”xpd”是映射到命名空间“http://example.com/2011/xpd”。下面的列表展示了这一文件可能的结构:

      

       媒体类型中这一类型所有信息可以描述记录在下面。请回到第四章我们学习MIME-info数据库去获取关于媒体类型记录结构进一步信息:

       教tika关于新的文件类型的最明显方式是扩展已知的媒体类型数据库,所以这就是第一步我们应该注重的。

 

11.1.1自定义媒体类型配置

       我们来看早些在第四章学习的共享的MIME-info数据库文件。数据库包含了在tika中所有已知的媒体类型信息,所以要支持一种新的类型需要将其加入到数据库中。这一节展示如何去做这一任务。

       在tika-core JAR中Tika默认从“org/apache/tika/mime/tika-mimetypes.xml”文件加载数据库。但是你也可以通过使用”MimeTypesFactory”类命令tika加载替换的文件。例如下面的列表说明了在类型检测中如何加载替换的MIME-info数据库和建立tika façade实例:

 

      当使用上述的自定义设置时,这一代码段将会返回期望的“application/x-prescription+xml”媒体类型。你也可以使用被“MimeTypesFactory”类返回“MimeTypes”类对象来创建”AutoDetectParser”实例或者任何你需要一个检测器对象的地方。

       Tika当前不支持合并多种MIME-info数据库,所以最好的创建自定义数据库的方式是在tika-coreJAR列入默认版本。不幸的是,这个意味着当tika新版本发布时你必须升级自定义的版本。将来的tika发布将毫无疑问的增加支持给数据库升级来使其更简单地维持各种各样的自定义扩展。

       现在,tika知道了我们定义的类型,下一步通过定制检测器类来添加更多的类型检测策略。

11.2自定义类型检测

       自定义MIME-info数据库使tika知道基于公共的特点检测(文件扩展名,魔数字节或XML元素)新的类型和新的类型检测规则。但是当我们处理更复杂的文件格式的时候,这些机制都没有起效怎么办?答案就在tika的检测器接口中,它允许我们加入自定义的类型检测算法。

       为了更好的理解检测器接口和作为扩展怎么使用,我们首先快速浏览接口的工作原理。然后我们再深入和实现加密处方文件的一个完整的自定义类型检测器。最后,再来看如何将自定义的检测器加入到tika。

11.2.1检测器接口

       检测器接口指定一个一般的API作为类型检测的算法。在接口中定义的detect方法检测基于文件的未处理的字节流和任何可得到的文档元数据来检测文件类型。下面的图是其如何工作的:

       一个检测器的实现能够查找字节流中已知的字节模式当另一个能够检测获得的文档元数据中的文件名后缀和别的媒体类型提示。当只处理文件名或原始字节流时,检测器的实现也应该准备好。如果检测器基于获取的信息不能够决定文档类型,就应该返回一般的“application/octet-stream”媒体类型。

       Tika将会自动地通过java的service提供机制加载所有的获取的检测器。当检测文档的类型时,所有的可得到的检测器以队列的顺序调用,返回最明确的媒体类型作为检测结果。你也可以通过实现检测器接口增加自定义媒体类型检测算法,增加需要的服务者设置。下一节将会展示实际中如何去做。

11.2.2创建自定义类型检测器

       例如,先假定前面所说的药房自动化系统应该自动地检测和处理送来的加密的邮件附件的数字处方。我们有解密的key,但是不能依靠这些文件扩展名或者其他的类型提示来检测这些文档。

       所以,我们应该如何去检测这些文档?正如前面所说的,解决办法是创建一个自定义的检测器类,将其放入tika的类型检测机制中。下面类所做的就是如此。

       这里发生了什么?依次分析这里的代码:

1.     首先,检测器类通过默认的构造方法被实例化,检测器不能通过解析环境对象(ParseContext)访问其他的设置,而解析器类可以。因此在这情况下,我们需要一个药房密钥的静态引用。

2.     然后在detect()方法中我们开始试图检测文档类型。这个方法能假定指定的流支持标记特点,在返回之前被期望设置流到原先的位置。org.apache.tika.io.LookaheadInputStream工具类对此是一个完美的工具,它关注所有管理流的状态的所有信息。在这个类的Javadocs中可以看到更多的说明信息。

3.     此后试图用标准java加密算法API解密lookahead流。如果解密失败,不管什么原因,我们可以假定文档未被加密或者没有正确的文档密钥。这个检测器类可以返回application/octet-stream作为返回类型。

4.     如果我们成功解密流,下一步的任务是检查是否类似XML并且以“xpd:prescription”元素开始。org.apache.tika.detect.XmlRootExtractor工具类被设计用于此目的,也被tika中默认的类型检测代码使用。

5.     最后,如果所有标记点是一个加密的数字处方文件,我们通过返回application/x-prescription类型告知tika。记录我们从类型名中丢弃了+xml后缀,因为加密使文档不可作为标准XML处理使用。这一新的媒体类型应该被加入到MIME-info数据库作为同属已经发布的XML类型。

11.2.3加入新的检测器

       在编译这自定义的检测器类之后你需要的最后一件事是把它加入到tika。最容易的方法是把编译的类文件放到JAR存档与META-INF/services/org.apache.tika.detect.Detector文件,其包含全部确认的类名。然后将JAR引入到classpath,tika将会自动的学习和使用新的检测器。

       如果你想在你的程序中更多的控制检测器的集合,你也可以使用ComositeDetector类来明确地组成集合。下面的代码块表示了如何去扩展我们前面的检测例子支持加密的处方文件:

目前为止学习了如何去扩展tika的媒体类型数据库和类型检测能力来覆盖任何你遇到的新类型文件。下一步则是让tika解析这类文档,这是下一节我们的关注点。

11.3自定义解析

       知道文档类型是有用的,但是能够抽取文档的信息是更好的。你需要去做解析的是文件格式,为此你使用第5章描述的解析器接口。让tika能够抽取新的文档类型的信息,第一步是实现一个新的解析器类或者扩展已存在的一个。这一节两个都会做。

       考虑我们前面一直讨论的数字处方文件。在他们的未加密形式特殊结构XML文档,加密形式将内部的XML文件用数字签名和加密包裹。为了更好地处理这些文件,我们需要两个新的解析器类,一个是基础的XML格式,另一个是加密形式。这些自定义解析器的关系如下图所示:

       正如图中所示,我们首先实现对未加密处方文件的支持,这通过继承tika中标准的XMLParser类。一旦我们有这个类,将会很轻松地结合其到先前的检测加密文档的工作实现一个加密数字处方自定义解析器。

11.3.1自定义已存在的解析器

       首先以你能在tika中找到的已存在的解析器。大多数时候它们工作都很好,但是如果你做一些小小的调整来帮助它们更好的分析你处理的各种文档呢?第5章我们学习的解析环境的对象允许一定程度的自定义,但是有时你需要解析器做更多的更改。

       Tika中很多的解析器类已经思想上使用自定义设计,所以你能够经常地用子类继承它们来覆写选中的方法。查看解析器类的Javadocs获取更多的信息关于它们能被继承的哪种形式。接下来使用的是XMLParser的继承例子。

       记住11.1节中的XML的基本的处方文档?文档包含分隔的元素如医生,病人,药物和任何的处方介绍。默认的XML解析器会读取这些所有元素,使其作为可获得解析结果。如果至少有一部分的字段可以作为元数据信息,那么能够使用吗?

       下面是一个示例类。它保留了XMLParser的默认属性同时映射“xpd:doctor”和”xpd:paitent”元素到元数据字段。

       让我们一步步地浏览这些代码来更好地理解怎么工作的:

1.     首先,这个类继承已存在的XMLParser,覆写了protected getContentHandler()方法。这一方法控制解析XML文件的SAX事件怎么映射到tika中的XHTML输出。默认的实现带出所有的元素,只传递文本内容给客户端。在这一情况下我们自定义这一项目映射选择的XML文档部分到相应的元数据字段。

2.     为了实现这个,我们使用org.apache.tika.parser.xml包中ElementMatadataHandler工具类。这个类解析进入的SAX事件流和映射文本内容中选择的元素到指定的元数据字段。在这一情况下,我们对处方中提到的医生和病人的名字感兴趣,所以我们创建两个handlers。

3.     我们使用TeeContentHandler类来将这些元数据处理和默认父类返回的XMLParser属性捆绑在一起。在第5章提到的TeeContentHandler查看更多的信息。

4.     最后覆写getSupportedTypes()方法,只返回application/x-prescription+xml媒体类型。这允许我们定义的类与默认的只支持标准的application/xml媒体类型的XMLParser类共存。

这不是太难,对吧?下面是创建一个全新的解析器类。

 

11.3.2写一个新的解析器

       你可能猜测:我们也需要一个解析加密处方文件的方式。因为tika中没有对加密文件格式的一般的解析器,我们需要写一个新的能够从加密处方中抽取信息的解析器。

       我们已经有了所有基本构造块从前面的例子中,所以仅剩下的是将这些块一起放到新的解析器类中。结果就如下面列出的:

 

       你可能能够讲出代码中每一块做了什么,但是还是一步步的进行分析以免丢失任何信息:

1.     我们以继承抽象的AbstractParser类开始而不是实现Parser接口。这个简单类有默认的实现给那些我们不必在代码中担忧过时的方法。

2.     主要的功能方法在parse()中,这个的属性我们在第五章详细学习了的。这里我们首先想解密那些加密的文件流,将XML内容传到我们创建的XML解析器中。

3.     因为我们将详细的解析过程授权给了另一个解析器类,我们不需要担忧类中的XHTML输出。除此之外,我们可以使用“XHTMLContentHandler”工具类(在第五章学习到的)。

4.     此后,我们实现getSupportedTypes()方法来告知tika使用这个解析器类处理文件的种类。返回的媒体类型应该和相应的检测器返回的类型匹配。

现在,我们有两个新的解析类文件:一个目的是未加密的,另一个是加密的数字处方文件。我们仍然需要告诉tika使用这些解析器,这是下一节要做的。

11.3.3加入新的解析器

       解析器插件就像检测器一样,在tika中默认使用服务提供机制加载从classpath中所有可获得的实现。为了告知tika关于你的两个新的解析器,你需要把编译后的文件放到JAR文件中的META-INF/services/org.apache.tika.parser.Parser(列出所有的认证了的解析器名字)文件一起。当你在路径中引入JAR文件之后,tika将会自动地开始使用这两个新的解析器。

       JAR文档这是一种容易的方式扩展tika。例如,你可以放这章节所有的代码到一个新的tika-xpd-1.0.0.jar文件与在META-INF/services的两个服务提供文件。然后,你将会有一个完整的tika插件你能在任何系统中轻松使用且支持数字处方使用tika获取元数据和内容抽取。

       所以如果你想覆写已存在的解析器在你有两个都支持同样的MIME类型的解析器将会发生什么?

11.3.4覆写已存在的解析器

       当你有两个都支持同一MIME类型的解析器,一小段代码能够帮助你确保期望被选择的解析器是被tika调用,正如下面:

  

在上图中,你首先声明MyCustomPrescriptionParser的实例。这是你希望被调用的解析器而不是默认的解析器被调用来处理application/x-prescription+xml类型。然后,为了将解析器与媒体类型连接一起,你可以通过创建一个AutoDetectParser实例与你的MyCustomPrescriptionParser作为解析器提供者构造装饰你的MyCustomPrescriptionParser。装饰者模式

11.4总结

       这一章节我们学习关于一个数字处方文件格式,尽管它是假定的,但却每天都在开发和使用的新文档格式中一个好的例子。能够容易检测,搜索,索引这类文件通常是一个重要的要求。Tika和其代表的这类工具集成了可以实现这样的要求有很大的帮助。你只需要扩展和帮助tika理解这些文件格式,就如我们在这一章节所做的。

       在简短的介绍示例的文件格式之后,我们关注如何使用基本的类型检测增加类型到tika的媒体类型数据库的信息。此后,我们学习更多的复杂的检测策略通过写一个自定义的检测器。最后,我们实现两个自定义的解析器类,一个继承和一个独立的,来让tika从我们的示例文档中抽取文件和元数据。所有的这些功能都被封装在JAR文档中,这是一个可以作为随时可用的插件功能在任何tika系统中扩展功能。

       这是本书的第三部分。现在你应该知道了关于tika相当多的内容了,即便是在自己程序中的复杂使用方式。下一部分我们将会讲在别的部分如何使用tika。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值