2010-03-31 75 views
3

我正在尝试索引Wikpedia dumps。我的SAX解析器仅使用我关心的字段为XML创建Article对象,然后将其发送到生成Lucene文档的ArticleSink。过滤维基百科的XML转储:某些口音错误

我要过滤特殊/元页面,如那些具有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)在小文件中被过滤,而不是在原始文件中...

任何想法?

替代我想:

获取文件(注释行进行了尝试 wihtout成功 *):

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 

*勘误

其实,是我不好,是一个我想工作,我测试了错误的指标:

InputSource is = new InputSource(fis); 
is.setEncoding("UTF-8"); // force UTF-8 interpretation 
parser.parse(fis, handler); 
+0

顺便提一下,维基百科XML文件在开头为标签指定了这些特殊前缀。通过SAX处理程序自动加载它们并没有改变剩下的问题。 – 2010-03-31 16:46:46

回答

2

既然你写的前缀为普通字符串转换为源文件,你要确保你保存。也可以使用UTF-8中的java文件(或任何其他支持您正在使用的特殊字符的编码)。然后,但是,你必须告诉编译器,编码文件是与-encoding标志:

javac -encoding utf-8 *.java 

对于XML源代码,你可以尝试

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

InputStreams不处理,因为编码它们是基于字节的,而不是基于字符的。因此,我们在这里创建一个来自FileInputStream的Reader--后者(流)不知道编码,但前者(读者)确实如此,因为我们在构造函数中给出编码。

+0

我的源代码已经编码并以UTF-8编译。至于你的尝试,这是ReaderInputStream.forceEncodingInputStream所做的,除了它将其重新转换回InputStream,因为SAXParser只支持二进制输入。 – 2010-03-31 12:50:40

+1

的SAXParser也需要'InputSource',你可以通过一个'Reader':'parser.parse(新的InputSource(R)处理器);' – Thomas 2010-03-31 14:54:25

+0

是的,我已经尝试过(见注释代码)。事实证明,我一定错过了一些东西,它甚至在我甚至在这里问过之前就有效。尽管如此,我还是接受了你的回答,因为这很好,并且感谢你的帮助。 – 2010-03-31 16:40:09