簡體   English   中英

使用XDocument循環瀏覽大型XML文件

[英]Loop through large XML file using XDocument

我必須將節點從現有XML文件復制到新創建的XML文件。 我正在使用XDocument實例來訪問現有XML文件。 問題在於XML文件可能很大(比如說50萬行; Openstreetmap數據)。

在大型XML文件中循環而不引起內存錯誤的最佳方法是什么?

我目前僅使用XDocument.Load(path)並遍歷doc.Descendants() ,但這會導致程序凍結直到循環完成。 因此,我認為我必須循環異步,但是我不知道實現此目標的最佳方法。

您可以使用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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM