如何在Delphi中使用MSXML SAX组合大型XML文件

时间:2011-08-04 14:13:25

标签: delphi com sax msxml6

修改GitHub

上提供了我的(不完整且非常粗糙)的XmlLite标题翻译

在不使用DOM的情况下,将Delphi中的大量XML文档与MSXML简单组合的最佳方法是什么?我应该使用COM组件SAXReader和XMLWriter吗?有什么好的例子吗?

转换是从根(Container)到许多大文件(60MB +)到一个巨大文件(~1GB)的所有Contents元素的简单组合。

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

我使用XmlWriter和XmlReaders在以下C#代码中工作,但它需要在本机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 个答案:

答案 0 :(得分:3)

XmlLite是来自System.Xml的xml读写器的本机C ++端口,它提供了拉解析编程模型。它与W2K3 SP2,WinXP SP3及更高版本配合使用。在从C#到Delphi的几乎1-1映射之前,你需要一个Delphi头转换。

答案 1 :(得分:1)

我只是使用常规文件I / O来写入文本文件,将每个内容写成字符串,最后写入。 如果你有一个更合理的大小,我会将所有内容组装在一个字符串列表中,然后将其流式传输到磁盘。但如果你进入GB领域,那将是有风险的。

答案 2 :(得分:1)

使用Delphi包装器libxml

Libxml2可能是一个选项(找到here),它有一些SAX支持并且看起来非常可靠 - 网页提到libxml2通过了所有来自OASIS XML Tests Suite的1800多项测试。 另见:Is there a SAX Parser for Delphi and Free Pascal?

答案 3 :(得分:0)

将此作为答案发布,因为它需要一些空格和格式。

我有一个用于测试的baaad数据文件,请参阅https://github.com/the-Arioch/omnixml/commit/d1a544048e86921983fced67c772944f12cb1427上的消息

这里的OmniXML在XE2调试版本中很糟糕:

  • 比TXmlDocument / MSXML多大约25%的内存使用量。修复后可能更多.NextSibling问题,没有重新测试。
  • 文件加载时间越长(OTOH读取节点属性明显越快:它们已经是Delphi类型的变量,没有跨越MSXML / Delphi边界)
  • 绝对不支持命名空间,这使识别标签更难
  • 处于胚胎状态的XPath,包括再次缺少命名空间

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