Vorgehensweise: Streamen von XML-Fragmenten aus einem XmlReader (C#)How to: Stream XML Fragments from an XmlReader (C#)

Wenn Sie große XML-Dateien verarbeiten müssen, kann u. U. nicht die gesamte XML-Struktur in den Arbeitsspeicher geladen werden.When you have to process large XML files, it might not be feasible to load the whole XML tree into memory. In diesem Thema wird gezeigt, wie mit einem XmlReader Fragmente gestreamt werden können.This topic shows how to stream fragments using an XmlReader.

Eine der effektivsten Möglichkeiten, einen XmlReader zum Lesen von XElement-Objekten zu verwenden, besteht darin, eine eigene benutzerdefinierte Achsenmethode zu schreiben.One of the most effective ways to use an XmlReader to read XElement objects is to write your own custom axis method. Achsenmethoden geben in der Regel eine Auflistung, z. B. die IEnumerable<T> von XElement zurück, wie dies im Beispiel in diesem Thema dargestellt ist.An axis method typically returns a collection such as IEnumerable<T> of XElement, as shown in the example in this topic. Nachdem Sie in der benutzerdefinierten Achsenmethode durch Aufrufen der ReadFrom-Methode das XML-Fragment erstellt haben, geben Sie die Auflistung mit yield return zurück.In the custom axis method, after you create the XML fragment by calling the ReadFrom method, return the collection using yield return. Auf diese Weise versehen Sie Ihre benutzerdefinierte Achsenmethode mit der Semantik für eine verzögerte Ausführung.This provides deferred execution semantics to your custom axis method.

Wenn Sie eine XML-Struktur auf der Grundlage eines XmlReader-Objekts erstellen, muss der XmlReader auf einem Element positioniert sein.When you create an XML tree from an XmlReader object, the XmlReader must be positioned on an element. Die ReadFrom-Methode gibt erst dann einen Wert zurück, wenn sie das Endtag des Elements gelesen hat.The ReadFrom method does not return until it has read the close tag of the element.

Wenn Sie eine Teilstruktur erstellen möchten, können Sie einen XmlReader instanziieren, den Reader auf dem Knoten positionieren, der in eine XElement-Struktur umgewandelt werden soll, und dann das XElement-Objekt erstellen.If you want to create a partial tree, you can instantiate an XmlReader, position the reader on the node that you want to convert to an XElement tree, and then create the XElement object.

Unter How to: Stream XML Fragments with Access to Header Information (C#) (Vorgehensweise: Streamen von XML-Fragmenten mit Zugriff auf Headerinformationen (C#)) finden Sie weitere Informationen und ein Beispiel, wie Sie ein komplexeren Dokument streamen können.The topic How to: Stream XML Fragments with Access to Header Information (C#) contains information and an example on how to stream a more complex document.

Unter How to: Perform Streaming Transform of Large XML Documents (C#) (vorgehensweise: Durchführen einer Streamingtransformation großer XML-Dokumente (C#)) finden Sie ein Beispiel für das Verwenden von LINQ to XML, um ein sehr großes XML-Dokument umzuwandeln, während Sie gleichzeitig eine geringe Speicherbeanspruchung beibehalten.The topic How to: Perform Streaming Transform of Large XML Documents (C#) contains an example of using LINQ to XML to transform extremely large XML documents while maintaining a small memory footprint.

BeispielExample

Dieses Beispiel erstellt eine benutzerdefinierte Achsenmethode.This example creates a custom axis method. Zum Abfragen kann eine LINQLINQ-Abfrage verwendet werden.You can query it by using a LINQLINQ query. Die benutzerdefinierte Achsenmethode StreamRootChildDoc eignet sich vor allem zum Lesen eines Dokuments, das ein sich wiederholendes Child-Element enthält.The custom axis method, StreamRootChildDoc, is a method that is designed specifically to read a document that has a repeating Child element.

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

Dieses Beispiel erzeugt die folgende Ausgabe:This example produces the following output:

bbb  
ccc  

In diesem Beispiel ist das Quelldokument sehr klein.In this example, the source document is very small. Dieses Beispiel würde aber auch dann wenig Speicher beanspruchen, wenn das Quelldokument Millionen Child-Elemente enthielte.However, even if there were millions of Child elements, this example would still have a small memory footprint.

Siehe auchSee Also

Analysieren von XML (C#)Parsing XML (C#)