我正在尝试索引Wikpedia dumps。我的SAX解析器只使用我关心的字段为XML创建Article对象,然后将其发送到我的ArticleSink,后者生成Lucene文档。
我想过滤那些以Category:
或Wikipedia:
为前缀的特殊/元页面,所以我创建了这些前缀的数组,并在我的ArticleSink中使用此数组测试每个页面的标题,使用article.getTitle.startsWith(prefix)
。在英语中,一切正常,我得到一个包含所有页面的Lucene索引,除了匹配的前缀。
在法语中,没有重音的前缀也起作用(即过滤相应的页面),一些重音前缀根本不起作用(如Catégorie:
),有些工作大部分时间但是失败在某些页面上(例如Wikipédia:
)但我看不到相应行之间的任何差异(在less
中)。
由于其大小(5 GB),我无法真正检查文件中的所有差异,但它看起来像是正确的UTF-8 XML。如果我使用grep
或head
获取文件的一部分,则重音是正确的(即使在有罪的网页上,<title>Catégorie:something</title>
正确显示grep
)。另一方面,当我通过尾部/头部剪切原始文件来直接创建wiki XML时,同一页面(此处Catégorie:Rock par ville
)会在小文件中过滤,而不是在原始文件中过滤...
有什么想法吗?
我试过的替代品:
获取文件(已尝试注释行没有成功 *):
FileInputStream fis = new FileInputStream(new File(xmlFileName));
//ReaderInputStream ris = ReaderInputStream.forceEncodingInputStream(fis, "UTF-8" );
//(custom function opening the stream,
//reading it as UFT-8 into a Reader and returning another byte stream)
//InputSource is = new InputSource( fis ); is.setEncoding("UTF-8");
parser.parse(fis, handler);
过滤前缀:
ignoredPrefix = new String[] {"Catégorie:", "Modèle:", "Wikipédia:",
"Cat\uFFFDgorie:", "Mod\uFFFDle:", "Wikip\uFFFDdia:", //invalid char
"Catégorie:", "Modèle:", "Wikipédia:", // UTF-8 as ISO-8859-1
"Image:", "Portail:", "Fichier:", "Aide:", "Projet:"}; // those last always work
* ERRATUM
实际上,我的不好,我试过的那个,我测试了错误的索引:
InputSource is = new InputSource( fis );
is.setEncoding("UTF-8"); // force UTF-8 interpretation
parser.parse(fis, handler);
答案 0 :(得分:2)
由于您将前缀作为纯字符串写入源文件,因此您需要确保将该 .java 文件保存为UTF-8(或任何其他支持特殊的编码)你正在使用的角色)。然而,然后,您必须告诉编译器该文件的编码位于-encoding
标志:
javac -encoding utf-8 *.java
对于XML源,您可以尝试
Reader r = new InputStreamReader(new FileInputStream(xmlFileName), "UTF-8");
InputStreams不处理编码,因为它们是基于字节的,而不是基于字符的。所以,这里我们从FileInputStream创建一个Reader - 后者(流)不知道编码,但前者(读者)会这样做,因为我们在构造函数中给出了编码。