【问题标题】:Loop through large XML file using XDocument使用 XDocument 循环遍历大型 XML 文件
【发布时间】:2016-12-04 23:45:48
【问题描述】:

我必须将节点从现有 XML 文件复制到新创建的 XML 文件。 我正在使用 XDocument 实例来访问现有的 XML 文件。问题是 XML 文件可能非常大(比如说 500K 行;Openstreetmap 数据)。

在不导致内存错误的情况下循环遍历大型 XML 文件的最佳方法是什么?

我目前只使用XDocument.Load(path) 并循环通过doc.Descendants(),但这会导致程序冻结,直到循环完成。所以我认为我必须循环异步,但我不知道实现这一点的最佳方法。

【问题讨论】:

  • XmlReaderIEnumerable 迭代器 (yield)

标签: c# xml


【解决方案1】:

您可以使用XmlReaderIEnumerable<XElement> 迭代器来生成您需要的元素。

这种方法不是异步的,但它可以节省内存,因为您不需要将整个文件加载到内存中进行处理。仅选择要复制的元素。

public IEnumerable<XElement> ReadFile(string pathToTheFile)
{
    using (XmlReader reader = XmlReader.Create(pathToTheFile))
    {
        reader.MoveToContent();
        while (reader.Read())
        {
            If (reader.NodeType == XmlNodeType.Element)
            {
                if (reader.Name.Equals("yourElementName"))
                {
                    XElement element = XElement.ReadFrom(reader) as XElement;
                    yield return element ;
                }
            }
        }
    }
}

可以异步读取文件

public async Task<IEnumerable<XElement>> ReadFileAsync(string pathToTheFile)
{
    var elements = new List<XElement>();
    var xmlSettings = new XmlReaderSettings { Async = true };
    using (XmlReader reader = XmlReader.Create(pathToTheFile, xmlSettings))
    {
        await reader.MoveToContentAsync();
        while (await reader.ReadAsync())
        {
            If (reader.NodeType == XmlNodeType.Element)
            {
                if (reader.Name.Equals("yourElementName"))
                {
                    XElement element = XElement.ReadFrom(reader) as XElement;
                    elements.Add(element);
                }
            }
        }
    }

    return elements;
}

然后你可以异步循环所有文件并等待结果

var fileTask1 = ReadFileAsync(filePath1);
var fileTask2 = ReadFileAsync(filePath2);
var fileTask3 = ReadFileAsync(filePath3);

await Task.WhenAll(new Task[] { fileTask1, fileTask2, fileTask3} );

// use results
var elementsFromFile1 = fileTask1.Result;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2013-01-26
    相关资源
    最近更新 更多