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

Edit: мой (неполный и очень грубый) перевод заголовка 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 ответов


как xmllite является родным портом C++ для чтения и записи xml из системы.Xml, который предоставляет модель программирования pull parsing. Он находится в коробке с W2K3 SP2, WinXP SP3 и выше. Вам понадобится перевод заголовка Delphi перед почти 1-1 сопоставлением с C# на Delphi.


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


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


Posting это как ответ, потому что ему нужно некоторое пространство и форматирование.

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

здесь OmniXML своего рода сосет в XE2 debug build:

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

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