【问题标题】:XMLReader to XML file using XMLWriter WriteNode - Very Slow for Large XML使用 XMLWriter WriteNode 的 XMLReader 到 XML 文件 - 大型 XML 非常慢
【发布时间】:2017-01-11 17:11:37
【问题描述】:

在 C# 中,我使用 SqlCommand ExecuteXmlReader() 调用 SQL Server 存储过程,该存储过程使用“For XML”返回大型 (1gb+) 复杂 XML 文件(多层次结构)。

ExecuteXmlReader() 返回一个 XmlReader,我希望将其保存到 XML 文件中。为此,我使用XmlWriter 将数据从XMLReader 流式传输到文件系统。

using (XmlReader xmlFromDatabase = xmlReaderFromDatabase)
{
  var settings = new XmlWriterSettings {Encoding = Encoding.UTF8, Indent = true};
  using (XmlWriter outputXmlFileToDisk = XmlWriter.Create(fileDirectory + fileName, settings))
  {
    outputXmlFileToDisk.WriteNode(xmlFromDatabase, false);
  }
}

旁注:我无法将整个 XML 加载到内存中 (XDocument),因为它太大了。

我的问题是WriteNode 非常慢 - 写入文件需要几个小时。如果我杀死我的应用程序,则写入磁盘上的 XML 文件将被部分写入,因为文件正在逐个节点地流式传输。

有没有比XMLWriter WriteNode 更快地从XmlReader 保存XML 的更好方法?

(我知道有 .ReadInnerXml() 但这会返回一个不适合 XML 大小的字符串)

导出文件后,需要对其进行转换(我可能会使用 Saxon,因为 .net 框架尚未证明其性能如我所愿)并通过 C# 对其进行架构验证。

【问题讨论】:

  • 在内部,XML 数据作为字符流从 SQL Server 传输(尽管内部类 SqlStream 和 XmlSqlBinaryReader)。因此,您可以使用以下技术将流直接复制到输出流中:stackoverflow.com/questions/29672383/…(没有尝试过,所以我不将此作为答案发布)
  • 另外,您可能想看看PrintXmlValuesViaNVarChar 示例,该示例显示了通过GetTextReader() 对XML 数据使用流和异步支持的热门:msdn.microsoft.com/en-us/library/hh556234(v=vs.110).aspx
  • 使用 SQL 工具保存比 c# 工具快得多。查看 SQLCMD.exe 和 BCP.exe。见msdn.microsoft.com/en-us/library/ms162816.aspx
  • 是WriteNode慢还是从服务器拉数据慢?
  • 从 SQL Server 拉取数据非常快,执行 ExecuteXmlReader 命令几分钟后,XMLReader 结果就可以使用了。不幸的是,当使用 XMLWriter 通过 XMLReader 流式传输时,WriteNode 需要花费数小时。由于需要其他文件管理器处理,我需要在 C# 中执行此操作,而不是使用 SQL Server 工具。有另一种方法还是我做错了什么? SQL Server --> 对于 XML SQL 查询(大型 XML 提取)--> XMLReader --> XMLWriter(使用 WriteNode)。

标签: c# xml xmlreader xmlwriter


【解决方案1】:

我找到了解决方案,使用XmlReader/XMLWriter 似乎是一种很好的方法(https://msdn.microsoft.com/en-us/library/ff647804.aspx),只是 XMLWriter-WriteNode 默认情况下会在写入时验证 XML。由于我们知道从 SQL Server 返回的 XML 是 XML 有效的,而且我们还在 XSD 验证所有 XML 之前发送它,我们不需要让编写器在写入时执行验证。使用 CheckCharacters = false 将 Settings 对象传递给 XMLWriter 可防止冗余验证,并在几分钟内输出文件。

var settings = new XmlWriterSettings{
            CheckCharacters = false,
            NewLineHandling = NewLineHandling.None,
            Indent = true,
            Encoding = Encoding.UTF8 };

using (var outputXmlFileToDisk = XmlWriter.Create(fileDirectory + fileName, settings))
{

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2020-08-19
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    相关资源
    最近更新 更多