XStreamingElement Klasse

Definition

Stellt Elemente in einer XML-Struktur dar, die verzögerte Streamingausgabe unterstützt.

public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
Vererbung
XStreamingElement

Beispiele

Im folgenden Beispiel wird zuerst eine XML-Quellstruktur erstellt. Anschließend wird eine Transformation der XML-Quellstruktur mithilfe XElementvon . Diese Transformation erstellt eine neue Struktur im Arbeitsspeicher. Anschließend wird eine Transformation der XML-Quellstruktur mithilfe XStreamingElementvon . Diese Transformation führt die Abfrage erst aus, wenn die transformierte Struktur in die Konsole serialisiert wird. Die Speicherauslastung ist geringer.

XElement srcTree = new XElement("Root",
                       new XElement("Child", 1),
                       new XElement("Child", 2),
                       new XElement("Child", 3),
                       new XElement("Child", 4),
                       new XElement("Child", 5)
                   );

XElement dstTree1 = new XElement("NewRoot",
                        from el in srcTree.Elements()
                        where (int)el >= 3
                        select new XElement("DifferentChild", (int)el)
                    );

XStreamingElement dstTree2 = new XStreamingElement("NewRoot",
                        from el in srcTree.Elements()
                        where (int)el >= 3
                        select new XElement("DifferentChild", (int)el)
                    );

Console.WriteLine(dstTree1);
Console.WriteLine("------");
Console.WriteLine(dstTree2);
Dim srcTree As XElement = _
        <Root>
            <Child>1</Child>
            <Child>2</Child>
            <Child>3</Child>
            <Child>4</Child>
            <Child>5</Child>
        </Root>

Dim dstTree1 As XElement = _
    <NewRoot>
        <%= From el In srcTree.Elements _
            Where (el.Value >= 3) _
            Select <DifferentChild><%= el.Value %></DifferentChild> %>
    </NewRoot>

Dim dstTree2 As XStreamingElement = New XStreamingElement("NewRoot", _
                From el In srcTree.Elements _
                Where el.Value >= 3 _
                Select <DifferentChild><%= el.Value %></DifferentChild> _
            )

Console.WriteLine(dstTree1)
Console.WriteLine("------")
Console.WriteLine(dstTree2)

Dieses Beispiel erzeugt die folgende Ausgabe:

<NewRoot>
  <DifferentChild>3</DifferentChild>
  <DifferentChild>4</DifferentChild>
  <DifferentChild>5</DifferentChild>
</NewRoot>
------
<NewRoot>
  <DifferentChild>3</DifferentChild>
  <DifferentChild>4</DifferentChild>
  <DifferentChild>5</DifferentChild>
</NewRoot>

Ein Ansatz zur Verarbeitung einer Textdatei besteht darin, eine Erweiterungsmethode zu schreiben, mit der die Textdatei jeweils mithilfe des yield return Konstrukts gestreamt wird. Anschließend können Sie eine LINQ-Abfrage schreiben, die die Textdatei in verzögerter Weise verarbeitet. Wenn Sie dann die XStreamingElement Ausgabe streamen, können Sie unabhängig von der Größe der Quelltextdatei eine Transformation aus der Textdatei in XML erstellen, die eine minimale Arbeitsspeichermenge verwendet.

Die folgende Textdatei, People.txt, ist die Quelle für dieses Beispiel.

#This is a comment
1,Tai,Yee,Writer
2,Nikolay,Grachev,Programmer
3,David,Wright,Inventor

Der folgende Code enthält eine Erweiterungsmethode, mit der die Zeilen der Textdatei verzögert gestreamt werden.

public static class StreamReaderSequence
{
    public static IEnumerable<string> Lines(this StreamReader source)
    {
        String line;

        if (source == null)
            throw new ArgumentNullException("source");
        while ((line = source.ReadLine()) != null)
        {
            yield return line;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        StreamReader sr = new StreamReader("People.txt");
        XStreamingElement xmlTree = new XStreamingElement("Root",
            from line in sr.Lines()
            let items = line.Split(',')
            where !line.StartsWith("#")
            select new XElement("Person",
                       new XAttribute("ID", items[0]),
                       new XElement("First", items[1]),
                       new XElement("Last", items[2]),
                       new XElement("Occupation", items[3])
                   )
        );
        Console.WriteLine(xmlTree);
        sr.Close();
    }
}
Module StreamReaderSequence

    <Runtime.CompilerServices.Extension>
    Public Iterator Function Lines(source As IO.StreamReader) As IEnumerable(Of String)
        If source Is Nothing Then Throw New ArgumentNullException("source")
        Dim line As String = source.ReadLine()
        While (line <> Nothing)
            Yield line
            line = source.ReadLine()
        End While
    End Function

End Module

Module Module1
    Sub Main()
        Dim sr As New IO.StreamReader("People.txt")
        Dim xmlTree As New XStreamingElement("Root",
            From line In sr.Lines()
            Let items = line.Split(","c)
            Where Not line.StartsWith("#")
            Select <Person ID=<%= items(0) %>>
                       <First><%= items(1) %></First>
                       <Last><%= items(2) %></Last>
                       <Occupation><%= items(3) %></Occupation>
                   </Person>)
        Console.WriteLine(xmlTree)
        sr.Close()
    End Sub
End Module

Dieses Beispiel erzeugt die folgende Ausgabe:

<Root>
  <Person ID="1">
    <First>Tai</First>
    <Last>Yee</Last>
    <Occupation>Writer</Occupation>
  </Person>
  <Person ID="2">
    <First>Nikolay</First>
    <Last>Grachev</Last>
    <Occupation>Programmer</Occupation>
  </Person>
  <Person ID="3">
    <First>David</First>
    <Last>Wright</Last>
    <Occupation>Inventor</Occupation>
  </Person>
</Root>

Manchmal müssen Sie große XML-Dateien transformieren und Ihre Anwendung so schreiben, dass der Speicherbedarf der Anwendung vorhersehbar ist. Wenn Sie versuchen, eine XML-Struktur mit einer sehr großen XML-Datei aufzufüllen, ist die Speicherauslastung proportional zur Größe der Datei (d. a. übermäßig). Daher sollten Sie stattdessen eine Streamingtechnik verwenden.

Bestimmte Standardabfrageoperatoren, z OrderBy. B. die Quelle durchlaufen, alle Daten sammeln, sortieren und schließlich das erste Element in der Sequenz liefern. Beachten Sie, dass Sie, wenn Sie einen Abfrageoperator verwenden, der seine Quelle vor dem Generieren des ersten Elements materialisiert, keinen kleinen Speicherbedarf für Ihre Anwendung beibehalten.

Auch wenn Sie die in diesem Abschnitt beschriebene Technik verwenden, kann die Speicherauslastung zu groß sein, wenn Sie versuchen, eine XML-Struktur zu erstellen, die das transformierte Dokument enthält.

Das folgende Beispiel baut auf dem Beispiel in how to stream XML fragments with access to header information auf.

In diesem Beispiel werden die Verzögerten Ausführungsfunktionen XStreamingElement verwendet, um die Ausgabe zu streamen.

Beachten Sie, dass die benutzerdefinierte Achse (StreamCustomerItem) speziell so geschrieben wird, dass ein Dokument mit Customer, Nameund Item Elementen erwartet wird und dass diese Elemente wie im folgenden Source.xml Dokument angeordnet werden. Eine robustere Implementierung würde jedoch entweder das Quelldokument mit einem XSD überprüfen oder bereit sein, ein ungültiges Dokument zu analysieren.

Es folgt das Quelldokument Source.xml:

<?xml version="1.0" encoding="utf-8" ?>
<Root>
  <Customer>
    <Name>A. Datum Corporation</Name>
    <Item>
      <Key>0001</Key>
    </Item>
    <Item>
      <Key>0002</Key>
    </Item>
    <Item>
      <Key>0003</Key>
    </Item>
    <Item>
      <Key>0004</Key>
    </Item>
  </Customer>
  <Customer>
    <Name>Fabrikam, Inc.</Name>
    <Item>
      <Key>0005</Key>
    </Item>
    <Item>
      <Key>0006</Key>
    </Item>
    <Item>
      <Key>0007</Key>
    </Item>
    <Item>
      <Key>0008</Key>
    </Item>
  </Customer>
  <Customer>
    <Name>Southridge Video</Name>
    <Item>
      <Key>0009</Key>
    </Item>
    <Item>
      <Key>0010</Key>
    </Item>
  </Customer>
</Root>

Der folgende Code enthält eine Methode, die zum XmlReader Streamen des Quell-XML-Codes verwendet wird. Es wird XStreamingElement verwendet, um den neuen XML-Code zu streamen.

static IEnumerable<XElement> StreamCustomerItem(string uri)
{
    using (XmlReader reader = XmlReader.Create(uri))
    {
        XElement name = null;
        XElement item = null;

        reader.MoveToContent();

        // Parse the file, save header information when encountered, and yield the
        // Item XElement objects as they are created.

        // loop through Customer elements
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element
                && reader.Name == "Customer")
            {
                // move to Name element
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element &&
                        reader.Name == "Name")
                    {
                        name = XElement.ReadFrom(reader) as XElement;
                        break;
                    }
                }

                // loop through Item elements
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.EndElement)
                        break;
                    if (reader.NodeType == XmlNodeType.Element
                        && reader.Name == "Item")
                    {
                        item = XElement.ReadFrom(reader) as XElement;
                        if (item != null)
                        {
                            XElement tempRoot = new XElement("Root",
                                new XElement(name)
                            );
                            tempRoot.Add(item);
                            yield return item;
                        }
                    }
                }
            }
        }
    }
}

static void Main(string[] args)
{
    XStreamingElement root = new XStreamingElement("Root",
        from el in StreamCustomerItem("Source.xml")
        select new XElement("Item",
            new XElement("Customer", (string)el.Parent.Element("Name")),
            new XElement(el.Element("Key"))
        )
    );
    root.Save("Test.xml");
    Console.WriteLine(File.ReadAllText("Test.xml"));
}
Iterator Function StreamCustomerItem(uri As String) As IEnumerable(Of XElement)

    Dim name As XElement = Nothing
    Dim item As XElement = Nothing

    Dim reader As XmlReader = XmlReader.Create(uri)
    reader.MoveToContent()

    ' Parse the file, save header information when encountered, and yield the
    ' Item XElement objects as they are created.

    ' Loop through Customer elements.
    While (reader.Read())
        If (reader.NodeType = XmlNodeType.Element And reader.Name = "Customer") Then
            While (reader.Read())
                ' Move to Name element
                If (reader.NodeType = XmlNodeType.Element And reader.Name = "Name") Then
                    name = CType(XElement.ReadFrom(reader), XElement)
                    Exit While
                End If
            End While

            ' Loop through Item elements
            While (reader.Read())
                If (reader.NodeType = XmlNodeType.EndElement) Then
                    Exit While
                End If

                If (reader.NodeType = XmlNodeType.Element And reader.Name = "Item") Then
                    item = CType(XElement.ReadFrom(reader), XElement)
                    If (Not (item Is Nothing)) Then
                        Dim tempRoot = New XElement("Root",
                            New XElement(name)
                        )
                        tempRoot.Add(item)
                        Yield item
                     End If
                End If
            End While
        End If
     End While
    reader.Close()
End Function

Sub Main()
    Dim root As New XStreamingElement("Root",
        From el In StreamCustomerItem("c:\trash\Source.xml")
        Select New XElement("Item",
            New XElement("Customer", CStr(el.Parent.Element("Name"))),
            New XElement(el.Element("Key"))))
    root.Save("c:\trash\Test.xml")
    Console.WriteLine(System.IO.File.ReadAllText("c:\trash\Test.xml"))
End Sub

Dieses Beispiel erzeugt die folgende Ausgabe:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Item>
    <Customer>A. Datum Corporation</Customer>
    <Key>0001</Key>
  </Item>
  <Item>
    <Customer>A. Datum Corporation</Customer>
    <Key>0002</Key>
  </Item>
  <Item>
    <Customer>A. Datum Corporation</Customer>
    <Key>0003</Key>
  </Item>
  <Item>
    <Customer>A. Datum Corporation</Customer>
    <Key>0004</Key>
  </Item>
  <Item>
    <Customer>Fabrikam, Inc.</Customer>
    <Key>0005</Key>
  </Item>
  <Item>
    <Customer>Fabrikam, Inc.</Customer>
    <Key>0006</Key>
  </Item>
  <Item>
    <Customer>Fabrikam, Inc.</Customer>
    <Key>0007</Key>
  </Item>
  <Item>
    <Customer>Fabrikam, Inc.</Customer>
    <Key>0008</Key>
  </Item>
  <Item>
    <Customer>Southridge Video</Customer>
    <Key>0009</Key>
  </Item>
  <Item>
    <Customer>Southridge Video</Customer>
    <Key>0010</Key>
  </Item>
</Root>

Hinweise

Mit dieser Klasse können Sie eine XML-Struktur erstellen, die verzögerte Streamingausgabe unterstützt. Sie verwenden diese Klasse, um eine XML-Struktur auf sehr ähnliche Weise zu erstellen wie das Erstellen einer XML-Struktur mithilfe XElementvon . Es gibt jedoch einen grundlegenden Unterschied. Wenn Sie beim Erstellen einer XML-Struktur XElementmithilfe einer LINQ-Abfrage Inhalte angeben, wird die Abfragevariable zum Zeitpunkt der Erstellung der XML-Struktur durchlaufen, und die Ergebnisse der Abfrage werden der XML-Struktur hinzugefügt. Wenn Sie dagegen eine XML-Struktur mithilfe XStreamingElementeiner XML-Struktur erstellen, wird ein Verweis auf die Abfragevariable in der XML-Struktur gespeichert, ohne iteriert zu werden. Abfragen werden nur bei der Serialisierung durchlaufen. Auf diese Weise können Sie größere XML-Strukturen erstellen und gleichzeitig einen geringeren Speicherbedarf beibehalten.

Wenn Sie aus einer Eingabequelle streamen, z. B. eine Textdatei, können Sie eine sehr große Textdatei lesen und ein sehr großes XML-Dokument generieren und gleichzeitig einen kleinen Speicherbedarf beibehalten.

Ein weiteres Szenario besteht darin, dass Sie über eine große XML-Struktur verfügen, die in den Arbeitsspeicher geladen wurde und Sie eine transformierte Version des Dokuments erstellen möchten. Wenn Sie ein neues Dokument mithilfe XElementeines neuen Dokuments erstellen, verfügen Sie nach Abschluss der Transformation über zwei große XML-Strukturen im Arbeitsspeicher. Wenn Sie jedoch die neue XML-Struktur mithilfe XStreamingElementder neuen XML-Struktur erstellen, wird Ihr Arbeitssatz effektiv in der Hälfte gekürzt.

Beachten Sie, dass beim Debuggen eines Programms, das XStreamingElementden Wert eines Objekts verwendet, dessen ToString Methode aufgerufen wird. Dies bewirkt, dass der XML-Code serialisiert wird. Wenn die Semantik Ihrer Streamingelementabfrage so ist, dass das Streamingelement nur einmal gestreamt werden kann, kann dies zu unerwünschtem Verhalten in Ihrer Debugumgebung führen.

Konstruktoren

Name Beschreibung
XStreamingElement(XName, Object)

Initialisiert eine neue Instanz der XStreamingElement Klasse mit dem angegebenen Namen und Inhalt.

XStreamingElement(XName, Object[])

Initialisiert eine neue Instanz der XStreamingElement Klasse mit dem angegebenen Namen und Inhalt.

XStreamingElement(XName)

Initialisiert eine neue Instanz der XElement Klasse aus dem angegebenen XName.

Eigenschaften

Name Beschreibung
Name

Ruft den Namen dieses Streamingelements ab oder legt diesen fest.

Methoden

Name Beschreibung
Add(Object)

Fügt den angegebenen Inhalt zu diesem XStreamingElementElement als untergeordnete Elemente hinzu.

Add(Object[])

Fügt den angegebenen Inhalt zu diesem XStreamingElementElement als untergeordnete Elemente hinzu.

Equals(Object)

Bestimmt, ob das angegebene Objekt dem aktuellen Objekt entspricht.

(Geerbt von Object)
GetHashCode()

Dient als Standardhashfunktion.

(Geerbt von Object)
GetType()

Ruft die Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie der aktuellen Object.

(Geerbt von Object)
Save(Stream, SaveOptions)

Gibt dies XStreamingElement an den angegebenen Stream, optional das Formatierungsverhalten an.

Save(Stream)

Gibt dies XStreamingElement an den angegebenen Wert aus Stream.

Save(String, SaveOptions)

Serialisieren Sie dieses Streamingelement in eine Datei, und deaktivieren Sie optional die Formatierung.

Save(String)

Serialisieren Sie dieses Streamingelement in eine Datei.

Save(TextWriter, SaveOptions)

Serialisieren Sie dieses Streamingelement auf eine TextWriterformatierungsbedingte Deaktivierung.

Save(TextWriter)

Serialisieren Sie dieses Streamingelement in ein TextWriter.

Save(XmlWriter)

Serialisieren Sie dieses Streamingelement in ein XmlWriter.

ToString()

Gibt den formatierten (eingerückten) XML-Code für dieses Streamingelement zurück.

ToString(SaveOptions)

Gibt den XML-Code für dieses Streamingelement zurück, optional wird die Formatierung deaktiviert.

WriteTo(XmlWriter)

Schreibt dieses Streamingelement in ein XmlWriter.

Gilt für:

Weitere Informationen