2010-03-31 28 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