如何:流式处理 XmlReader 中的 XML 片段

更新:November 2007

如果必须处理很大的 XML 文件,将整个 XML 树加载到内存可能不可行。本主题演示如何使用 XmlReader 对片段进行流式处理。

使用 XmlReader 读取 XElement 对象的一种最有效方式是编写您自己的自定义轴方法。轴方法通常会返回一个集合,比如 XElementIEnumerable<T>,如本主题中的示例所示。在自定义轴方法中,在通过调用 ReadFrom 方法创建 XML 片段后,可以使用 yield return 返回该集合。这可为您的自定义轴方法提供延迟执行语义。

在从 XmlReader 对象创建 XML 树时,XmlReader 必须位于元素上。ReadFrom 方法在读取该元素的结束标记之前不会返回。

如果想要创建一个部分树,可实例化 XmlReader,将读取器定位在要转换为 XElement 树的节点上,然后创建 XElement 对象。

如何:流处理可访问标头信息的 XML 片段主题包含有关如何流式处理更复杂文档的信息和示例。

如何:执行大型 XML 文档的流式转换主题包含如何使用 LINQ to XML 在保持小内存需求量的同时转换极大 XML 文档的示例。

示例

本示例创建一个自定义轴方法。可以通过使用 LINQ 查询来查询该方法。自定义轴方法 StreamRootChildDoc 是一个专门设计的方法,用于读取具有重复 Child 元素的文档。

说明:

下面的示例使用 C# 的 yield return 构造。由于 Visual Basic 2008 中没有等效的功能,因此只提供 C# 示例。

static IEnumerable<XElement> StreamRootChildDoc(StringReader stringReader)
{
    using (XmlReader reader = XmlReader.Create(stringReader))
    {
        reader.MoveToContent();
        // Parse the file and display each of the nodes.
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    if (reader.Name == "Child") {
                        XElement el = XElement.ReadFrom(reader) as XElement;
                        if (el != null)
                            yield return el;
                    }
                    break;
            }
        }
    }
}

static void Main(string[] args)
{
    string markup = @"<Root>
      <Child Key=""01"">
        <GrandChild>aaa</GrandChild>
      </Child>
      <Child Key=""02"">
        <GrandChild>bbb</GrandChild>
      </Child>
      <Child Key=""03"">
        <GrandChild>ccc</GrandChild>
      </Child>
    </Root>";

    IEnumerable<string> grandChildData =
        from el in StreamRootChildDoc(new StringReader(markup))
        where (int)el.Attribute("Key") > 1
        select (string)el.Element("GrandChild");

    foreach (string str in grandChildData) {
        Console.WriteLine(str);
    }
}

本示例生成以下输出:

bbb
ccc

在本示例中,源文档非常小。但是即使有数百万个 Child 元素,本示例也仍具有很小的内存需求量。

请参见

概念

分析 XML