我正在开发一个应用程序,它将对不同格式的大文件(将它们分成多个org.apache.lucene.document.Documents)进行Lucene索引。至少在最初的方法中,每个“Lucene文档”由一个“段落”组成。
作为一般规则,Apache Tika似乎是一个天赐之物:你只需要在它上面放一个文档,无论格式如何,它都会出现所有文本。
但是我希望得到一些关于如何处理棘手方面的详细知识,并且在我第一次看到它处理脚注和尾注的过程中,我发现在.docx文件中它会给出这个“行” “,对于一个有3个脚注的行:
|Tecum optime[footnoteRef:2], deinde etiam[footnoteRef:3] cum mediocri amico[footnoteRef:4].
[2: Sed quoniam et advesperascit et mihi ad villam revertendum est, nunc quidem hactenus;
Quod si ita sit, cur opera philosophiae sit danda nescio.] [3: Si quae forte-possumus.
Immo videri fortasse.] [4: Huius ego nunc auctoritatem [sequens idem faciam]. Confecta
res esset. Primum Theophrasti, Strato, physicum se voluit; Ut proverbia non nulla veriora
sint quam vestra dogmata.]|
(注意,为了清楚起见,我的代码添加了“|”字符)
...使用.doc格式的相同文件Tika为您提供了多个“行”:
|Tecum optime|
|, deinde etiam|
| cum mediocri amico|
|.|
...
|??|
| ? Sed quoniam et advesperascit et mihi ad villam revertendum est, nunc quidem
hactenus; Quod si ita sit, cur opera philosophiae sit danda nescio. |
|??|
| ? Si quae forte-possumus. Immo videri fortasse. |
|??|
| ? Huius ego nunc auctoritatem [sequens idem faciam]. Confecta res esset. Primum
Theophrasti, Strato, physicum se voluit; Ut proverbia non nulla veriora sint quam
vestra dogmata. |
...它不仅将原来的“段落”分成几行,在每个脚注引用中打破,但它也将所有脚注推到处理结束。
使用.docx文件处理,您可以提取脚注并轻松将它们链接到它们所属的句子。 .doc处理的工作方式当然对我的索引目的无益。事实上,我无法真正看到一种方式,即最初的4“线”可以被识别为真正属于同一个副词。
也许可以预料到Tika处理像.doc这样过时的格式并不是那么美妙。我现在打算看看这里涉及的实际源代码,假设我可以在Gradle下载的众多源jar中找到它,而不是调整代码是否有更“传统”的修改Tika的方法解析给定的格式?我做了一些搜索,但一无所获。
当然,另一种方法可能是将.doc文件(和.odt文件,见下文)转换为.docx“动态”,以获得更高质量的解析。
PS解析LibreOffice .odt文件(Open Document Format,ODF),一种非过时的格式,同样存在问题。特别是,含脚注/尾注的行同样被分成多个线。
答案 0 :(得分:0)
我对几天后感兴趣的人的调查结果。
首先,似乎阿帕奇人并不打算在Tika课程中捣乱。
当试图调整MS Word 97-2003格式(又名.doc)的处理时,这里涉及的主要类是HWPFDocument
(“可怕的文字处理格式”)。 Apache POI项目的一部分,与Tika捆绑在一起。
这个类通常从.doc文件中获取InputStream
,并且似乎将文件的不同元素拆分得相当无用,因此脚注等似乎与文本分开存储。 HWPFDocument
是final
,这只是问题的开始:这里的许多文件都依赖于包中或子包中的其他类,其中许多是final
或不是public
{ {1}}(或protected
)。我得出的结论是,我基本上必须克隆整个org.apache.poi.hwpf
包,对其进行处理并再次打包。我无法打扰。
.odt(ODF)文件类型最终对我来说非常重要:非过时和非Micro $ oft。在这里,关键的课程结果是org.apache.tika.parser.odf.OpenDocumentContentParser
。这里的问题是它包含一个private final
内部类(即它们真的不希望你将它子类化,甚至出于某种原因使用它的实例!)名为{{1最终实现OpenDocumentElementMappingContentHandler
。有数百个(好的,很多的)org.xml.sax.ContentHandler
- 在这里涉及实现类,其中许多是“装饰器”。但最终你需要做的是复制这个类ContentHandler
的整个代码然后搞乱内部类。我这样做是为了在OpenDocumentContentParser
和startElement
,根据参数endElement
的值,它切换到或出一个可能值“UNDEFINED”的“解析模式” NOTE_CITATION“或”NODE BODY“......并且根据此模式设置可取消呼叫
qName
super.endElement(namespaceURI, localName, qName);
中的。正是这个endElement
调用似乎触发了一个字符串的结尾和下一个字符串的开头。要在输出文本中输入脚注编号或正文的文本指示,您可以创建super
然后转到
String injectedText
如果适当的话。这是因为实际上 的最终super.characters( injectedText.toCharArray(), 0, injectedText.length());
是ContentHandler
的一个实例,ToTextContentHandler
方法只添加了一个characters( ... )
到chars
个实例的序列(是的,我从来没有听说过这个:很简单)。
希望这会有所帮助。现在已经将这个新类别提交给Tika项目,看看他们是否喜欢它的外观。