【问题标题】:How to do streaming read of a large XML file in C# 3.5如何在 C# 3.5 中对大型 XML 文件进行流式读取
【发布时间】:2025-12-15 01:40:01
【问题描述】:

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

【问题讨论】:

    标签: c# .net xml .net-3.5 streaming


    【解决方案1】:

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

    当前:

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

    固定:

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

    【讨论】:

      【解决方案2】:

      使用 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);
            }
          }
        }
      }
      

      【讨论】:

      • 我注意到的几件事:catch 语句在错误的位置(应该在倒数第二个右大括号之后),并且在最后一个 break 语句之后有一个额外的右大括号(它试图关闭 case 语句,但您只关闭 switch 语句)。另外,我找不到 StartElement 方法的来源,或者它应该是一个虚拟方法来替换为用户代码?
      【解决方案3】:

      该代码示例尝试将 XmlReader 样式代码转换为 SAX 样式代码 - 如果您是从头开始编写代码,我会按照预期使用 XmlReader - 拉取而不是推送。

      【讨论】:

        【解决方案4】:

        我对“xs:sequence”的提及感到困惑——这是一个 XML Schema 元素。

        您是否正在尝试打开一个大型 XML 架构文件?您是否打开了基于该架构的大型 XML 文件?或者您是否尝试打开一个大型 XML 文件并同时对其进行验证?

        这些情况都不会给您使用标准 XmlReader(或 XmlValidatingReader)带来问题。

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

        【讨论】:

          【解决方案5】:

          这是一个操作方法:http://support.microsoft.com/kb/301228/en-us 请记住,您不应该使用 XmlTextReader,而应将 XmlReader 与 XmlReader.Create 结合使用

          【讨论】:

            【解决方案6】:

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

            XmlReader 类读取 XML 数据 来自流或文件。它提供 非缓存、只进、只读 访问 XML 数据。

            【讨论】: