如何在C#3.5中流式读取大型XML文件

时间:2020-03-05 18:48:06  来源:igfitidea点击:

如何在不包含整个文件到内存中的XDocument实例的情况下,在根元素正下方包含xs:sequence的大型XML文件上进行流式读取?

解决方案

回答

我认为如果要使用对象模型(即XElement \ XDocument)查询XML是不可能的。显然,如果不读取足够的数据就无法构建XML对象树。但是,我们可以使用XmlReader类。

The XmlReader class reads XML data
  from a stream or file. It provides
  non-cached, forward-only, read-only
  access to XML data.

回答

这是一个方法:http://support.microsoft.com/kb/301228/zh-cn请记住,我们不应该使用XmlTextReader,而应将XmlReader与XmlReader.Create结合使用。

回答

我对提到" xs:sequence"感到困惑,这是一个XML Schema元素。

我们是否要打开大的XML Schema文件?我们是否正在打开基于该架构的大型XML文件?还是要尝试打开一个大型XML文件并同时进行验证?

在这些情况下,使用标准XmlReader(或者XmlValidatingReader)都不会给我们带来问题。

使用XMLReader读取XML:http://msdn.microsoft.com/zh-cn/library/9d83k261(VS.80).aspx

回答

可以使用SAX样式的元素解析器和XmlReader.Create创建的XmlTextReader类。这是CodeGuru的稍作修改的代码示例:

void ParseURL(string strUrl)
{
  try
  {
    using (var reader = XmlReader.Create(strUrl))
    {
      while (reader.Read())
      {
        switch (reader.NodeType)
        {
          case XmlNodeType.Element:
            var attributes = new Hashtable();
            var strURI = reader.NamespaceURI;
            var strName = reader.Name;
            if (reader.HasAttributes)
            {
              for (int i = 0; i < reader.AttributeCount; i++)
              {
                reader.MoveToAttribute(i);
                attributes.Add(reader.Name,reader.Value);
              }
            }
            StartElement(strURI,strName,strName,attributes);
            break;
            //
            //you can handle other cases here
            //
            //case XmlNodeType.EndElement:
            // Todo
            //case XmlNodeType.Text:
            // Todo
            default:
            break;
          }
        }
      }
      catch (XmlException e)
      {
        Console.WriteLine("error occured: " + e.Message);
      }
    }
  }
}

回答

如果我们是从头开始编写代码,那么该代码示例将尝试将XmlReader样式代码转换为SAX样式代码,我只是使用XmlReader,因为它原本是Pull而不是Push。

回答

因为我刚刚注册,但是我无法添加评论,但是Hirvox发布并当前被选择为答案的代码示例中存在错误。使用静态Create方法时,它不应该具有new语句。

当前的:

using (var reader = new XmlReader.Create(strUrl))

固定的:

using (var reader = XmlReader.Create(strUrl))