过滤维基百科的XML转储:某些重音错误

时间:2010-03-31 10:40:42

标签: java xml character-encoding

我正在尝试索引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。如果我使用grephead获取文件的一部分,则重音是正确的(即使在有罪的网页上,<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);

1 个答案:

答案 0 :(得分:2)

由于您将前缀作为纯字符串写入源文件,因此您需要确保将该 .java 文件保存为UTF-8(或任何其他支持特殊的编码)你正在使用的角色)。然而,然后,您必须告诉编译器该文件的编码位于-encoding标志:

javac -encoding utf-8 *.java

对于XML源,您可以尝试

Reader r = new InputStreamReader(new FileInputStream(xmlFileName), "UTF-8");

InputStreams不处理编码,因为它们是基于字节的,而不是基于字符的。所以,这里我们从FileInputStream创建一个Reader - 后者(流)不知道编码,但前者(读者)会这样做,因为我们在构造函数中给出了编码。