XStreamingElement Klas

Definitie

Vertegenwoordigt elementen in een XML-structuur die ondersteuning biedt voor uitgestelde streaming-uitvoer.

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

Voorbeelden

In het volgende voorbeeld wordt eerst een XML-bronstructuur gemaakt. Vervolgens wordt een transformatie van de XML-bronstructuur gemaakt met behulp van XElement. Met deze transformatie maakt u een nieuwe structuur in het geheugen. Vervolgens wordt een transformatie van de XML-bronstructuur gemaakt met behulp van XStreamingElement. Met deze transformatie wordt de query pas uitgevoerd als de getransformeerde structuur naar de console wordt geserialiseerd. Het geheugengebruik is minder.

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)

In dit voorbeeld wordt de volgende uitvoer gegenereerd:

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

Een benadering voor het verwerken van een tekstbestand is het schrijven van een extensiemethode waarmee het tekstbestand een regel tegelijk wordt gestreamd met behulp van de yield return constructie. Vervolgens kunt u een LINQ-query schrijven waarmee het tekstbestand op een vertraagde uitgestelde manier wordt verwerkt. Als u de XStreamingElement uitvoer vervolgens gebruikt om uitvoer te streamen, kunt u een transformatie maken van het tekstbestand naar XML die een minimale hoeveelheid geheugen gebruikt, ongeacht de grootte van het brontekstbestand.

Het volgende tekstbestand, People.txt, is de bron voor dit voorbeeld.

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

De volgende code bevat een extensiemethode die de regels van het tekstbestand op een uitgestelde manier streamt.

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

In dit voorbeeld wordt de volgende uitvoer gegenereerd:

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

Soms moet u grote XML-bestanden transformeren en uw toepassing schrijven, zodat de geheugenvoetafdruk van de toepassing voorspelbaar is. Als u een XML-structuur met een zeer groot XML-bestand probeert te vullen, is het geheugengebruik evenredig met de grootte van het bestand (dat wil gezegd overmatig). Daarom moet u in plaats daarvan een streamingtechniek gebruiken.

Bepaalde standaardqueryoperators, zoals OrderByhet herhalen van hun bron, verzamelen alle gegevens, sorteren en vervolgens het eerste item in de reeks opleveren. Als u een queryoperator gebruikt die de bron materialiseert voordat u het eerste item opgeeft, behoudt u geen kleine geheugenvoetafdruk voor uw toepassing.

Zelfs als u de techniek gebruikt die wordt beschreven in , als u een XML-structuur probeert samen te stellen die het getransformeerde document bevat, kan het geheugengebruik te groot zijn.

Het volgende voorbeeld is gebaseerd op het voorbeeld in XML-fragmenten streamen met toegang tot headergegevens.

In dit voorbeeld worden de uitgestelde uitvoeringsmogelijkheden gebruikt om XStreamingElement de uitvoer te streamen.

Houd er rekening mee dat de aangepaste as (StreamCustomerItem) specifiek is geschreven, zodat een document met Customer, Nameen Item elementen wordt verwacht en dat deze elementen worden gerangschikt zoals in het volgende Source.xml document. Een krachtigere implementatie zou echter het brondocument valideren met een XSD of bereid zijn om een ongeldig document te parseren.

Hier volgt het brondocument, 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>

De volgende code bevat een methode die gebruikmaakt van een XmlReader methode om de bron-XML te streamen. XStreamingElement Hiermee wordt de nieuwe XML gestreamd.

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

In dit voorbeeld wordt de volgende uitvoer gegenereerd:

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

Opmerkingen

Met deze klasse kunt u een XML-structuur maken die ondersteuning biedt voor uitgestelde streaming-uitvoer. U gebruikt deze klasse om een XML-structuur op een zeer vergelijkbare manier te maken als het maken van een XML-structuur met behulp van XElement. Er is echter een fundamenteel verschil. Wanneer u een LINQ-query gebruikt om inhoud op te geven bij het maken van een XML-structuur met behulp XElementvan, wordt de queryvariabele op het moment van de bouw van de XML-structuur curseren en worden de resultaten van de query toegevoegd aan de XML-structuur. Wanneer u daarentegen een XML-structuur maakt met behulp XStreamingElementvan, wordt een verwijzing naar de queryvariabele opgeslagen in de XML-structuur zonder dat deze wordt ge curseerd. Query's worden alleen na serialisatie geïnserieerd. Hierdoor kunt u grotere XML-structuren maken terwijl u een kleinere geheugenvoetafdruk behoudt.

Als u streamt vanuit een invoerbron, zoals een tekstbestand, kunt u een zeer groot tekstbestand lezen en een zeer groot XML-document genereren terwijl u een kleine geheugenvoetafdruk behoudt.

Een ander scenario is dat u een grote XML-structuur hebt die in het geheugen is geladen en u een getransformeerde versie van het document wilt maken. Als u een nieuw document maakt met behulp van XElement, hebt u twee grote XML-structuren in het geheugen nadat de transformatie is voltooid. Als u echter de nieuwe XML-structuur maakt met behulp van XStreamingElement, wordt uw werkset effectief geknipt in de helft.

Houd er rekening mee dat bij het opsporen van fouten in een programma dat gebruikmaakt XStreamingElementvan de waarde van een object ToString , de methode wordt aangeroepen. Hierdoor wordt de XML geserialiseerd. Als de semantiek van uw streaming-elementquery zodanig is dat het streaming-element slechts eenmaal kan worden gestreamd, kan dit ongewenst gedrag veroorzaken in uw foutopsporingservaring.

Constructors

Name Description
XStreamingElement(XName, Object)

Initialiseert een nieuw exemplaar van de XStreamingElement klasse met de opgegeven naam en inhoud.

XStreamingElement(XName, Object[])

Initialiseert een nieuw exemplaar van de XStreamingElement klasse met de opgegeven naam en inhoud.

XStreamingElement(XName)

Initialiseert een nieuw exemplaar van de XElement klasse van de opgegeven XName.

Eigenschappen

Name Description
Name

Hiermee haalt u de naam van dit streaming-element op of stelt u deze in.

Methoden

Name Description
Add(Object)

Hiermee voegt u de opgegeven inhoud toe als onderliggende elementen.XStreamingElement

Add(Object[])

Hiermee voegt u de opgegeven inhoud toe als onderliggende elementen.XStreamingElement

Equals(Object)

Bepaalt of het opgegeven object gelijk is aan het huidige object.

(Overgenomen van Object)
GetHashCode()

Fungeert als de standaardhashfunctie.

(Overgenomen van Object)
GetType()

Hiermee haalt u de Type huidige instantie op.

(Overgenomen van Object)
MemberwiseClone()

Hiermee maakt u een ondiepe kopie van de huidige Object.

(Overgenomen van Object)
Save(Stream, SaveOptions)

Hiermee wordt dit XStreamingElement uitgevoerd naar het opgegeven Stream, eventueel opmaakgedrag opgeven.

Save(Stream)

Hiermee wordt dit XStreamingElement uitgevoerd naar de opgegeven Stream.

Save(String, SaveOptions)

Serialiseer dit streaming-element naar een bestand, optioneel het uitschakelen van opmaak.

Save(String)

Serialiseer dit streaming-element naar een bestand.

Save(TextWriter, SaveOptions)

Serialiseer dit streaming-element naar een TextWriter, optioneel uitschakelen van opmaak.

Save(TextWriter)

Serialiseer dit streaming-element naar een TextWriter.

Save(XmlWriter)

Serialiseer dit streaming-element naar een XmlWriter.

ToString()

Retourneert de opgemaakte (ingesprongen) XML voor dit streaming-element.

ToString(SaveOptions)

Retourneert de XML voor dit streaming-element, optioneel het uitschakelen van opmaak.

WriteTo(XmlWriter)

Hiermee schrijft u dit streaming-element naar een XmlWriter.

Van toepassing op

Zie ook