Sdílet prostřednictvím


XStreamingElement Třída

Definice

Představuje prvky ve stromu XML, který podporuje výstup odloženého streamování.

public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
Dědičnost
XStreamingElement

Příklady

Následující příklad nejprve vytvoří zdrojový strom XML. Pak vytvoří transformaci zdrojového stromu XML pomocí XElement. Tato transformace vytvoří v paměti nový strom. Pak vytvoří transformaci zdrojového stromu XML pomocí XStreamingElement. Tato transformace nespustí dotaz, dokud se transformovaný strom serializuje do konzoly. Využití paměti je menší.

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)  

Tento příklad vytvoří následující výstup:

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

Jedním z přístupů ke zpracování textového souboru je zápis rozšiřující metody, která streamuje textový soubor řádek najednou pomocí konstruktoru yield return . Pak můžete napsat dotaz LINQ, který zpracovává textový soubor opožděným odloženým způsobem. Pokud pak použijete XStreamingElement k streamování výstupu, můžete vytvořit transformaci z textového souboru na XML, která používá minimální velikost paměti bez ohledu na velikost zdrojového textového souboru.

Následující textový soubor People.txt je zdrojem tohoto příkladu.

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

Následující kód obsahuje rozšiřující metodu, která streamuje řádky textového souboru odloženým způsobem.

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  

Tento příklad vytvoří následující výstup:

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

Někdy musíte transformovat velké soubory XML a zapsat aplikaci tak, aby nároky na paměť aplikace byly předvídatelné. Pokud se pokusíte naplnit strom XML velmi velkým souborem XML, bude využití paměti úměrné velikosti souboru (to znamená nadměrné). Proto byste měli místo toho použít metodu streamování.

Některé standardní operátory dotazů, jako OrderByje například iterace jejich zdroje, shromáždí všechna data, seřadí je a nakonec vyvolají první položku v posloupnosti. Všimněte si, že pokud použijete operátor dotazu, který materializuje jeho zdroj před vydáním první položky, neuchováváte pro aplikaci malou paměťovou stopu.

I když použijete techniku popsanou v tématu , pokud se pokusíte sestavit strom XML, který obsahuje transformovaný dokument, může být využití paměti příliš velké.

Následující příklad vychází z příkladu v části Jak streamovat fragmenty XML s přístupem k informacím hlavičky.

V tomto příkladu se k streamování výstupu XStreamingElement používají možnosti odloženého spuštění.

Všimněte si, že vlastní osa (StreamCustomerItem) je speciálně napsaná tak, aby očekávala dokument, který obsahuje Customer, Namea Item prvky a že tyto prvky budou uspořádány jako v následujícím Source.xml dokumentu. Robustnější implementace by však buď ověřila zdrojový dokument pomocí XSD, nebo by byla připravena analyzovat neplatný dokument.

Tady je zdrojový dokument 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>  

Následující kód obsahuje metodu, která používá XmlReader k streamování zdrojového XML. Používá XStreamingElement se k streamování nového 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  

Tento příklad vytvoří následující výstup:

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

Poznámky

Tato třída umožňuje vytvořit strom XML, který podporuje odložený výstup streamování. Tuto třídu použijete k vytvoření stromu XML velmi podobným způsobem jako vytvoření stromu XML pomocí XElement. Existuje však zásadní rozdíl. Pokud použijete dotaz LINQ k určení obsahu při vytváření stromu XML pomocí XElement, proměnná dotazu se iterated v době vytvoření stromu XML a výsledky dotazu se přidají do stromu XML. Naproti tomu při vytváření stromu XML pomocí XStreamingElement, odkaz na proměnnou dotazu je uložen ve stromu XML bez iterated. Dotazy jsou iterated pouze při serializaci. Díky tomu můžete vytvářet větší stromy XML při zachování menší paměti.

Pokud streamujete ze vstupního zdroje, například z textového souboru, můžete přečíst velmi velký textový soubor a vygenerovat velmi velký dokument XML a zachovat tak malou paměťovou stopu.

Dalším scénářem je, že máte velký strom XML, který byl načten do paměti, a chcete vytvořit transformovanou verzi dokumentu. Pokud vytvoříte nový dokument pomocí XElement, po dokončení transformace budete mít v paměti dva velké stromy XML. Pokud však vytvoříte nový strom XML pomocí XStreamingElement, pracovní sada se bude efektivně snížit na polovinu.

Všimněte si, že při ladění programu, který používá XStreamingElement, zobrazení hodnoty objektu způsobí, že jeho ToString metoda bude volána. To způsobí serializaci XML. Pokud je sémantika dotazu prvku streamování taková, že element streamování lze streamovat pouze jednou, může to způsobit nežádoucí chování v prostředí ladění.

Konstruktory

XStreamingElement(XName)

Inicializuje novou instanci XElement třídy ze zadané XName.

XStreamingElement(XName, Object)

Inicializuje novou instanci XStreamingElement třídy se zadaným názvem a obsahem.

XStreamingElement(XName, Object[])

Inicializuje novou instanci XStreamingElement třídy se zadaným názvem a obsahem.

Vlastnosti

Name

Získá nebo nastaví název tohoto streamovacího prvku.

Metody

Add(Object)

Přidá zadaný obsah jako podřízené položky do tohoto XStreamingElementsouboru .

Add(Object[])

Přidá zadaný obsah jako podřízené položky do tohoto XStreamingElementsouboru .

Equals(Object)

Určí, zda se zadaný objekt rovná aktuálnímu objektu.

(Zděděno od Object)
GetHashCode()

Slouží jako výchozí funkce hash.

(Zděděno od Object)
GetType()

Type Získá aktuální instanci.

(Zděděno od Object)
MemberwiseClone()

Vytvoří použádnou kopii aktuálního souboru Object.

(Zděděno od Object)
Save(Stream)

Výstupem je XStreamingElement zadaný Stream.

Save(Stream, SaveOptions)

Vypíše toto XStreamingElement do zadaného Stream, volitelně určení chování formátování.

Save(String)

Serializovat tento streamovací prvek do souboru.

Save(String, SaveOptions)

Serializace tohoto streamovacího prvku do souboru, volitelně zakázání formátování.

Save(TextWriter)

Serializace tohoto streamovacího prvku na TextWriter.

Save(TextWriter, SaveOptions)

Serializace tohoto streamovacího prvku na TextWriter, volitelně zakázání formátování.

Save(XmlWriter)

Serializovat tento streamovací prvek na XmlWriter.

ToString()

Vrátí formátovaný (odsazený) XML pro tento prvek streamování.

ToString(SaveOptions)

Vrátí xml pro tento element streamování, volitelně zakázání formátování.

WriteTo(XmlWriter)

Zapíše tento streamovací prvek do objektu XmlWriter.

Platí pro

Viz také