2016-12-03 5 views
0

Ich mag würde Wikimedia .xml.bzip2 analysieren Dumps, ohne die gesamte Datei zu extrahieren oder eine XML-Validierung durchführen:Lesen sehr große .xml.bz2 Dateien

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"); 
    // ... 
} 

Die BZip2InputStream Werke - wenn ich einen StreamReader verwenden Ich kann XML Zeile für Zeile lesen. Aber wenn ich XmlTextReader verwenden, scheitert es, wenn ich versuche, die Lese auszuführen:

System.Xml.XmlException: ‚Unerwartetes Ende der Datei aufgetreten ist. Die folgenden Elemente sind nicht geschlossen: mediawiki. Linie 58, Position 1. '

Der bzip Strom nicht bei EOF. Ist es möglich, einen XmlTextReader über einem BZip2-Stream zu öffnen? Oder gibt es andere Möglichkeiten, dies zu tun?

+0

Die Dateien sind ZIP-Dateien (GZ) und die GZ enthält einen einzelnen Artikel. Wenn der gz mehrere Dateien enthielt, könnten Sie den Index lesen und eine einzelne Datei extrahieren. Da der gz eine einzige Datei enthält, müssen Sie die gesamte Datei herunterladen und extrahieren, bevor Sie die XML-Daten analysieren können. – jdweng

+1

"Sehr groß" ist bedeutungslos: es kann alles von 1 MB bis 1 TB bedeuten. Wenn Sie uns keine Nummer geben können, erwähnen Sie bitte nicht die Größe. –

+0

@jdweng - dieser Dump ist eine einzelne, sehr große XML-Datei, die alle von Wikipedia enthält - kein Tarball einzelner Dateien. – user655321

Antwort

0

Dies sollte funktionieren. Ich habe eine Kombination aus XmlReader und Xml Linq verwendet. Sie können das XElement-Dokument nach Bedarf analysieren.

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

Danke, obwohl dies immer noch die XML-Eingabedatei verwendet, nicht die komprimierte XML. Ich kann diesen Code im Grunde für meine lokale Datei verwenden, wenn ich dekomprimiere, aber das Binden des BZip2InputStream mit einem XmlReader löst immer noch dieselbe Ausnahme aus. – user655321

+0

Als ich die Datei früher heruntergeladen habe, konnte ich die Datei nicht direkt in Chrome lesen. Ich musste die Datei auf die Festplatte speichern. Ich frage mich, ob Sie die Datei vor dem Öffnen auf die Festplatte ftp, wenn Sie den gleichen Fehler erhalten. Ich habe meinen Code nicht versucht, die gesamte Datei von der URL zu lesen. Frage mich, ob der gleiche Fehler auftritt. – jdweng