2011-01-30 229 views
3

我有一個很大的維基百科轉儲,我想分割成不同的文件(每篇文章1個文件)。我寫了一個VB應用程序來爲我做,但它很緩慢,並在切割幾個小時後被廢棄。我目前使用另一個應用程序將文件分割成更小的50mb塊,但這需要很長時間(每個塊大約20-30分鐘)。如果我這樣做,我應該可以分別切割每一個。將大型XML文件分割成小塊

有沒有人有任何建議,以更快地切割這個文件?

回答

0

我假設你正在使用DOM解析器。對於潛在的大文件,您應該始終使用SAX解析器。 DOM解析器將整個文件讀入內存,SAX解析器每次讀取的次數儘可能少,因此可以更高效地運行。 This tutorial描述瞭如何編寫一個C#SAX解析器,VB應該非常相似。

3

使用C#執行此操作的最簡單方法是使用XmlReader。您可以單獨使用XmlReader以實現最快的實現,或者與新的LINQ XNode類結合使用,以獲得體面的性能和易用性。有關示例,請參閱此MSDN文章:http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx

您應該可以修改示例,使其僅將一個文檔的節點一次保存在內存中,然後將其作爲文件重新寫回。它應該表現良好,適用於非常大的文件。

0

如果我這樣做在Java中,我會使用javax.xml.stream.XMLEventReaderjavax.xml.stream.XMLEventWriter

在某種僞代碼,讓我們假設一個<article>標籤界定每個維基百科的文章,你不必擔心嵌套<article>標籤,和你有一個openNewWriter()函數打開一個新的XMLEventWriter寫入到一個新文件爲這篇文章命名。

然後我的代碼看起來像這樣的事情:

XMLEventReader r = // an XMLEventReader for the original wikipedia dump 

XMLEventWriter w = null; 

bool isInsideArticle = false; 

while (r.hasNext()){ 
    XMLEvent e = r.nextEvent(); 

    if (e.isStartElement() && 
     e.asStartElement().getName().getLocalPart().equals("article")){ 
    w = openNewWriter(); 
    // write the stuff that belongs outside the <article> tag 
    // by synthesizing XMLEvents and using w.add() to add them 
    w.add(e); 
    isInsideArticle = true; 
    } else if (e.isEndElement() && 
      e.asEndElement().getName().getLocalPart().equals("article")) { 
    w.add(e); 
    // write the stuff that belongs outside the <article> tag 
    // by synthesizing XMLEvents and using w.add() to add them 
    isInsideArticle = false; 
    w.close(); 
    } else if (isInsideArticle) { 
    w.add(e); 
    } else { 
    // this tag gets dropped on the floor because it's not inside any article 
    } 
} 

現在你需要做的是找到.NET中的流XML類。我認爲他們是system.xml.XMLReadersystem.xml.XMLWriter,但我的專業知識不在.NET中,我無法從文檔中知道他們是否會像我剛給你的Java版本那樣工作。

(我這裏的目的更多的是向你展示如何解決問題,而不是告訴你需要的類的名字。)

相關問題