XStreamingElement Klasa

Definicja

Reprezentuje elementy w drzewie XML, które obsługuje odroczone dane wyjściowe przesyłania strumieniowego.

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

Przykłady

Poniższy przykład najpierw tworzy źródłowe drzewo XML. Następnie tworzy przekształcenie źródłowego drzewa XML przy użyciu polecenia XElement. Ta transformacja tworzy nowe drzewo w pamięci. Następnie tworzy przekształcenie źródłowego drzewa XML przy użyciu polecenia XStreamingElement. Ta transformacja nie wykonuje zapytania, dopóki przekształcone drzewo nie zostanie serializowane w konsoli. Jego użycie pamięci jest mniejsze.

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)  

Ten przykład generuje następujące wyniki:

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

Jednym z podejść do przetwarzania pliku tekstowego jest napisanie metody rozszerzenia, która przesyła strumieniowo plik tekstowy wiersz naraz przy użyciu yield return konstrukcji. Następnie można napisać zapytanie LINQ, które przetwarza plik tekstowy w sposób opóźniony z opóźnieniem. Jeśli następnie użyjesz XStreamingElement elementu do przesyłania strumieniowego danych wyjściowych, możesz utworzyć przekształcenie z pliku tekstowego na XML, który używa minimalnej ilości pamięci, niezależnie od rozmiaru pliku tekstowego źródłowego.

Poniższy plik tekstowy, People.txt, jest źródłem dla tego przykładu.

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

Poniższy kod zawiera metodę rozszerzenia, która przesyła strumieniowo wiersze pliku tekstowego w sposób odroczony.

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  

Ten przykład generuje następujące wyniki:

<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>  

Czasami trzeba przekształcić duże pliki XML i napisać aplikację tak, aby zużycie pamięci przez aplikację było przewidywalne. Jeśli spróbujesz wypełnić drzewo XML bardzo dużym plikiem XML, użycie pamięci będzie proporcjonalne do rozmiaru pliku (czyli nadmiernego). Dlatego zamiast tego należy użyć techniki przesyłania strumieniowego.

Niektóre standardowe operatory zapytań, takie jak OrderBy, iterują swoje źródło, zbierają wszystkie dane, sortują je, a następnie w końcu dają pierwszy element w sekwencji. Należy pamiętać, że jeśli używasz operatora zapytania, który materializuje jego źródło przed uzyskaniem pierwszego elementu, nie zachowasz niewielkiego zużycia pamięci dla aplikacji.

Nawet jeśli używasz techniki opisanej w temacie , jeśli spróbujesz utworzyć drzewo XML zawierające przekształcony dokument, użycie pamięci może być zbyt duże.

Poniższy przykład opiera się na przykładzie w temacie How to stream XML fragments with access to header information (Jak przesyłać strumieniowo fragmenty XML z dostępem do informacji nagłówka).

W tym przykładzie użyto możliwości odroczonego XStreamingElement wykonywania w celu przesyłania strumieniowego danych wyjściowych.

Należy pamiętać, że oś niestandardowa (StreamCustomerItem) jest napisana specjalnie tak, aby oczekiwała dokumentu z Customerelementami , Namei oraz Item że te elementy zostaną rozmieszczone tak, jak w poniższym dokumencie Source.xml. Bardziej niezawodna implementacja może jednak zweryfikować dokument źródłowy za pomocą XSD lub przygotować się do analizowania nieprawidłowego dokumentu.

Poniżej przedstawiono dokument źródłowy, 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>  

Poniższy kod zawiera metodę, która używa XmlReader obiektu do strumieniowego przesyłania strumieniowego kodu XML. Używa XStreamingElement go do przesyłania strumieniowego nowego kodu XML.

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  

Ten przykład generuje następujące wyniki:

<?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>  

Uwagi

Ta klasa umożliwia utworzenie drzewa XML obsługującego odroczone dane wyjściowe przesyłania strumieniowego. Ta klasa służy do tworzenia drzewa XML w bardzo podobny sposób do tworzenia drzewa XML przy użyciu polecenia XElement. Istnieje jednak podstawowa różnica. Gdy używasz zapytania LINQ do określania zawartości podczas tworzenia drzewa XML przy użyciu XElement, zmienna kwerendy jest iteracja w czasie konstruowania drzewa XML, a wyniki zapytania są dodawane do drzewa XML. Z kolei podczas tworzenia drzewa XML przy użyciu metody XStreamingElementodwołanie do zmiennej kwerendy jest przechowywane w drzewie XML bez iterated. Zapytania są iterowane tylko po serializacji. Dzięki temu można tworzyć większe drzewa XML przy zachowaniu mniejszego zużycia pamięci.

Jeśli przesyłasz strumieniowo ze źródła wejściowego, takiego jak plik tekstowy, możesz odczytać bardzo duży plik tekstowy i wygenerować bardzo duży dokument XML przy zachowaniu małej ilości pamięci.

Innym scenariuszem jest to, że masz duże drzewo XML, które zostało załadowane do pamięci, i chcesz utworzyć przekształconą wersję dokumentu. Jeśli tworzysz nowy dokument przy użyciu polecenia XElement, po zakończeniu transformacji będziesz mieć dwa duże drzewa XML w pamięci. Jeśli jednak utworzysz nowe drzewo XML przy użyciu polecenia XStreamingElement, zestaw roboczy zostanie skutecznie obcięty na pół.

Należy pamiętać, że podczas debugowania programu, który używa XStreamingElementmetody , wyświetlanie wartości obiektu powoduje wywołanie jego ToString metody. Powoduje to serializację kodu XML. Jeśli semantyka zapytania elementu przesyłania strumieniowego jest taka, że element przesyłania strumieniowego może być przesyłany strumieniowo tylko raz, może to spowodować niepożądane zachowanie w środowisku debugowania.

Konstruktory

XStreamingElement(XName)

Inicjuje XElement nowe wystąpienie klasy z określonego XNameelementu .

XStreamingElement(XName, Object)

Inicjuje XStreamingElement nowe wystąpienie klasy o określonej nazwie i zawartości.

XStreamingElement(XName, Object[])

Inicjuje XStreamingElement nowe wystąpienie klasy o określonej nazwie i zawartości.

Właściwości

Name

Pobiera lub ustawia nazwę tego elementu przesyłania strumieniowego.

Metody

Add(Object)

Dodaje określoną zawartość jako elementy podrzędne do tego XStreamingElementelementu .

Add(Object[])

Dodaje określoną zawartość jako elementy podrzędne do tego XStreamingElementelementu .

Equals(Object)

Określa, czy dany obiekt jest taki sam, jak bieżący obiekt.

(Odziedziczone po Object)
GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetType()

Type Pobiera wartość bieżącego wystąpienia.

(Odziedziczone po Object)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Objectelementu .

(Odziedziczone po Object)
Save(Stream)

Zwraca tę wartość XStreamingElement do określonego Streamelementu .

Save(Stream, SaveOptions)

Zwraca to XStreamingElement do określonego Streamelementu , opcjonalnie określając zachowanie formatowania.

Save(String)

Serializuj ten element przesyłania strumieniowego do pliku.

Save(String, SaveOptions)

Serializuj ten element przesyłania strumieniowego do pliku, opcjonalnie wyłączając formatowanie.

Save(TextWriter)

Serializuj ten element przesyłania strumieniowego do elementu TextWriter.

Save(TextWriter, SaveOptions)

Serializuj ten element przesyłania strumieniowego TextWriterdo elementu , opcjonalnie wyłączając formatowanie.

Save(XmlWriter)

Serializuj ten element przesyłania strumieniowego do elementu XmlWriter.

ToString()

Zwraca sformatowany (wcięcie) kod XML dla tego elementu przesyłania strumieniowego.

ToString(SaveOptions)

Zwraca kod XML dla tego elementu przesyłania strumieniowego, opcjonalnie wyłączając formatowanie.

WriteTo(XmlWriter)

Zapisuje ten element przesyłania strumieniowego w obiekcie XmlWriter.

Dotyczy

Zobacz też