2016-12-03 98 views
0

我想解析維基媒體的.xml.bzip2轉儲無需解壓整個文件或執行任何XML驗證:閱讀非常大的.xml.bz2文件

var filename = "enwiki-20160820-pages-articles.xml.bz2"; 

var settings = new XmlReaderSettings() 
{ 
    ValidationType = ValidationType.None, 
    ConformanceLevel = ConformanceLevel.Auto // Fragment ? 
}; 

using (var stream = File.Open(filename, FileMode.Open)) 
using (var bz2 = new BZip2InputStream(stream)) 
using (var xml = XmlTextReader.Create(bz2, settings)) 
{ 
    xml.ReadToFollowing("page"); 
    // ... 
} 

BZip2InputStream作品 - 如果我使用一個StreamReader ,我可以逐行閱讀XML。但是當我使用XmlTextReader時,嘗試執行讀操作時失敗:

System.Xml.XmlException:'發生意外的文件結尾。以下元素未關閉:mediawiki。第58行,位置1。

在EOF處的bzip流是而不是。是否可以在BZip2流的頂部打開一個XmlTextReader?還是有其他方法可以做到這一點?

+0

這些文件是zip文件(gz),gz包含一篇文章。如果gz包含多個文件,那麼您可以讀取索引並提取一個文件。由於gz包含單個文件,因此必須下載整個文件並進行解壓縮,然後才能解析xml數據。 – jdweng

+1

「非常大」是毫無意義的:它可以表示任何從1Mb到1Tb的內容。如果你不能給我們一個號碼,那麼不要提及大小。 –

+0

@jdweng - 這個轉儲是一個包含所有維基百科的單個非常大的XML文件,而不是單個文件的tarball。 – user655321

回答

0

這應該工作。我使用了XmlReader和Xml Linq的組合。您可以根據需要解析XElement文檔。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 


namespace ConsoleApplication29 
{ 
    class Program 
    { 
     const string URL = @"https://dumps.wikimedia.org/enwiki/20160820/enwiki-20160820-abstract26.xml"; 
     static void Main(string[] args) 
     { 
      XmlReader reader = XmlReader.Create(URL); 

      while (!reader.EOF) 
      { 
       if (reader.Name != "doc") 
       { 
        reader.ReadToFollowing("doc"); 
       } 
       if (!reader.EOF) 
       { 
        XElement doc = (XElement)XElement.ReadFrom(reader); 
       } 
      } 

     } 
    } 
} 
+0

謝謝,雖然這仍然使用XML輸入文件,而不是壓縮的XML。當我解壓縮時,我基本上可以在本地文件上使用此代碼,但用XmlReader封裝BZip2InputStream仍然會引發相同的異常。 – user655321

+0

當我更早地下載文件時,我無法直接將文件讀入chrome。我必須將文件保存到磁盤。我想知道如果你在打開之前將文件ftp到磁盤,如果你得到相同的錯誤。我沒有嘗試我的代碼從URL讀取整個文件。想知道是否發生相同的錯誤。 – jdweng