将大型XML文件切割成小块

时间:2011-01-30 05:19:12

标签: xml vb.net wikipedia

我有一个大的维基百科转储,我想切成不同的文件(每篇文章1个文件)。我写了一个VB应用程序来为我做这个,但它很慢,并在切割几个小时后被废弃。我目前正在使用另一个应用程序将文件拆分为较小的50mb块,但这需要很长时间(每个块需要20-30分钟)。如果我这样做,我应该能够单独削减每一个。

有没有人建议更快地删除此文件?

4 个答案:

答案 0 :(得分:3)

使用C#执行此操作的最简单方法是使用XmlReader。您可以单独使用XmlReader来实现最快的实现,或者与新的LINQ XNode类结合使用,以获得性能和易用性的完美结合。有关示例,请参阅此MSDN文章:http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx

您应该能够修改示例,以便一次仅在内存中保存一个文档的节点,然后将其作为文件写回。它应该运行良好,适用于非常大的文件。

答案 1 :(得分:0)

我假设你正在使用DOM解析器。对于可能较大的文件,您应始终使用SAX解析器。 DOM解析器将整个文件读入内存,SAX解析器一次尽可能少地读取,因此运行效率更高。 This tutorial描述了如何编写C#SAX解析器,VB应该非常相似。

答案 2 :(得分: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版本完全相同给了你。

(我的目的是向您展示如何处理问题,而不是告诉您所需类的名称。)

答案 3 :(得分:-1)

你应该试试vtd-xml,我们让人们告诉我们拆分大型XML文件的效果如何...... http://www.codeproject.com/KB/XML/xml_processing_future.aspx 我们也被告知DOM需要永远