如何处理大型xml文件

时间:2013-02-11 06:59:13

标签: c# .net xml filestream

public XmlNodeList GetNodes(string _logFilePath, string _strXPathQuery)
        {    
                    objXmlDoc = new XmlDocument();
                    objXmlDoc.Load(_logFilePath);
                    XmlNodeList objxmlNodeList = objXmlDoc.SelectNodes(_strXPathQuery);
                    return objxmlNodeList;
        }

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<AppXmlLogWritter>
<LogData>
<LogID>999992013021110381000001</LogID>
<LogDateTime>20130211103810</LogDateTime>
<LogType>Message</LogType>
<LogFlag>Flag</LogFlag>
<LogApplication>Application</LogApplication>
<LogModule>Module</LogModule>
<LogLocation>Location</LogLocation>
<LogText>Text</LogText>
<LogStackTrace>Stacktrace</LogStackTrace>
</LogData>
</AppXmlLogWritter>

这里Xml文件大小为1000MB,当我将它加载到xmlDocument对象然后给我一个OutOf内存异常。因为XMLDocument将节点存储到Memory。我使用Xpath查询通过xml文件过滤节点。然后绑定到listview显示节点。 我阅读了有关如何处理大型XML文件的文章,他们告诉我使用XpathQuery。                     但问题没有解决。 文件流怎么样?或任何其他想法加载大型xml文件? *

2 个答案:

答案 0 :(得分:3)

您可以编写一个方法,使用XmlReader以块的形式读取大型XML文件。

首先设计一个包含数据的模型:

public class LogData
{
    public string LogID { get; set; }
    public string LogDateTime { get; set; }
    public string LogType { get; set; }
    ...
}

然后是一个解析XML文件的方法:

public static IEnumerable<LogData> GetLogData(XmlReader reader)
{
    LogData logData = null;
    while (reader.Read())
    {
        if (reader.IsStartElement("LogData"))
        {
            logData = new LogData();
        }
        if (reader.Name == "LogData" && reader.NodeType == XmlNodeType.EndElement)
        {
            yield return logData;
        }
        if (reader.Name == "LogID")
        {
            logData.LogID = reader.ReadElementContentAsString();
        }
        else if (reader.Name == "LogDateTime")
        {
            logData.LogDateTime = reader.ReadElementContentAsString();
        }
        else if (reader.Name == "LogType")
        {
            logData.LogType = reader.ReadElementContentAsString();
        }
        ...
    }
}

现在您只能加载要显示的元素。例如:

using (var reader = XmlReader.Create("someHugeFile.xml"))
{
    IEnumerable<LogData> data = GetLogData(reader).Skip(10).Take(5);
    // Go ahead and bind the data to your UI
}

您可能想知道的另一件事是您在XML文件中总共有多少条记录,以便有效地实现分页。这可以通过另一种方法完成:

public static int GetTotalLogEntries(XmlReader reader)
{
    var count = 0;
    while (reader.Read())
    {
        if (reader.IsStartElement("LogData"))
        {
            count++;
        }
    }
    return count;
}

答案 1 :(得分:0)

我建议您在将xml邮件发送到流之前压缩它,然后在另一端收到它后将其解压缩。在WCF中,您可以像http://www.codeproject.com/Articles/165844/WCF-Client-Server-Application-with-Custom-Authenti#Compression

那样执行此操作