Как объединить большие файлы XML с помощью MSXML SAX в Delphi - PullRequest
8 голосов
/ 04 августа 2011

Редактировать: Мой (неполный и очень грубый) перевод заголовка XmlLite доступен на GitHub

Как лучше всего объединить массивные XML-документы в Delphi с MSXML без использования DOM? Стоит ли использовать COM-компоненты SAXReader и XMLWriter и есть ли хорошие примеры?

Преобразование представляет собой простую комбинацию всех элементов содержимого из корня (контейнера) из множества больших файлов (60 МБ +) в один большой файл (~ 1 ГБ).

<Container>
    <Contents />
    <Contents />
    <Contents />
</Container>

Он работает в следующем коде C # с использованием XmlWriter и XmlReaders, но это должно происходить в нативном процессе Delphi:

var files = new string[] { @"c:\bigFile1.xml", @"c:\bigFile2.xml", @"c:\bigFile3.xml", @"c:\bigFile4.xml", @"c:\bigFile5.xml", @"c:\bigFile6.xml" };

using (var writer = XmlWriter.Create(@"c:\HugeOutput.xml", new XmlWriterSettings{ Indent = true }))
{
    writer.WriteStartElement("Container");

    foreach (var inputFile in files)
        using (var reader = XmlReader.Create(inputFile))
        {
            reader.MoveToContent();
            while (reader.Read())
                if (reader.IsStartElement("Contents"))
                    writer.WriteNode(reader, true);
        }

    writer.WriteEndElement(); //End the Container element
}

Мы уже используем MSXML DOM в других частях системы, и я не хочу добавлять новые компоненты, если это возможно.

Ответы [ 4 ]

3 голосов
/ 07 августа 2011

XmlLite - это собственный порт C ++ для чтения и записи XML-файлов из System.Xml, который предоставляет модель программирования для синтаксического анализа. Он поставляется с W2K3 SP2, WinXP SP3 и выше. Вам понадобится перевод заголовка Delphi перед почти 1-1 отображением из C # в Delphi.

1 голос
/ 04 августа 2011

libxml с оберткой Delphi Libxml2 может быть опцией (найдено здесь ), имеет некоторую поддержку SAX и кажется очень надежной - ИнтернетНа странице упоминается, что libxml2 прошел все 1800+ тестов из OASIS XML Tests Suite.Смотрите также: Есть ли SAX Parser для Delphi и Free Pascal?

1 голос
/ 04 августа 2011

Я бы просто использовал обычный файловый ввод / вывод для записи в текстовый файл, записи каждого содержимого в виде строки и, наконец, записи. Если бы у вас был более разумный размер, я бы собрал все в списке строк, а затем передал бы его на диск. Но если вы находитесь на территории Великобритании, это будет рискованно.

0 голосов
/ 04 октября 2016

Публикуем это как ответ, потому что это требует некоторого пространства и форматирования.

У меня есть один файл данных baaad для тестов, см. Сообщение в https://github.com/the-Arioch/omnixml/commit/d1a544048e86921983fced67c772944f12cb1427

Здесь вид OmniXML отстой в отладочной сборке XE2:

  • Примерно на 25% больше используемой памяти, чем в TXmlDocument / MSXML. Может быть, даже больше после исправления проблемы .NextSibling, не перепроверять.
  • более длительное время загрузки файла (OTOH значительно быстрее считывает свойства узла: они уже являются переменными типа Delphi, пересечение границы MSXML / Delphi отсутствует)
  • абсолютно не поддерживает пространства имен, что затрудняет распознавание тегов
  • XPath в зачаточном состоянии, включая еще раз отсутствие пространств имен

https://docs.google.com/spreadsheets/d/1QcFVwh3fFfaDyRmv2b-n4Rq4_u5p42UfNbR_FZgZizY/edit?usp=sharing

...