2011-01-30 8 views
3

У меня есть большой дамп википедии, который я хочу вырезать в разные файлы (по 1 файлу для каждой статьи). Я написал приложение VB, чтобы сделать это для меня, но он был довольно медленным и вылетел после нескольких часов резки. Im в настоящее время разбивает файл на более мелкие куски размером 50 МБ, используя другое приложение, но это занимает много времени (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.

Вы должны иметь возможность изменить пример, чтобы одновременно удерживать узел только для одного документа в памяти, а затем записывать его в виде файла. Он должен хорошо работать и работать с очень большими файлами.

-1

Вы должны попробовать ВТД-XML для этого, у нас есть люди, которые говорят нам, насколько хорошо она работает для разбиения больших XML-файлов ... http://www.codeproject.com/KB/XML/xml_processing_future.aspx мы также сказали, что DOM принимает навсегда

0

Если бы я делал это в Java, я бы использовал javax.xml.stream.XMLEventReader и javax.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 
    } 
} 

Теперь все, что вам нужно сделать, это найти классы потокового XML в .NET. Я думаю, что они system.xml.XMLReader и system.xml.XMLWriter, но мой опыт не в .NET, и я не могу сказать из документации, будут ли они работать так же, как и Java-версия, которую я вам только что дал.

(Моя цель здесь, чтобы показать вам, как подойти к проблеме, чем рассказать вам имена нужных вам классов.)

Смежные вопросы