XStreamingElement Classe

Définition

Représente les éléments d'une arborescence XML qui prend en charge la sortie de diffusion en continu différée.

public ref class XStreamingElement
public class XStreamingElement
type XStreamingElement = class
Public Class XStreamingElement
Héritage
XStreamingElement

Exemples

L’exemple suivant crée d’abord une arborescence XML source. Il crée ensuite une transformation de l’arborescence XML source à l’aide XElementde . Cette transformation crée une arborescence en mémoire. Il crée ensuite une transformation de l’arborescence XML source à l’aide XStreamingElementde . Cette transformation n’exécute pas la requête tant que l’arborescence transformée n’est pas sérialisée dans la console. Son utilisation de la mémoire est inférieure.

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)  

Cet exemple produit la sortie suivante :

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

L'une des façons de traiter un fichier texte consiste à écrire une méthode d'extension qui diffuse en continu le fichier texte une ligne à la fois à l'aide de la construction yield return. Vous pouvez alors écrire une requête LINQ qui traite le fichier texte de manière différée. Si vous utilisez ensuite le XStreamingElement flux de sortie, vous pouvez créer une transformation du fichier texte au format XML qui utilise une quantité minimale de mémoire, quelle que soit la taille du fichier texte source.

Le fichier texte suivant, People.txt, est la source pour cet exemple.

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

Le code suivant contient une méthode d'extension qui diffuse en continu les lignes du fichier texte de manière différée.

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  

Cet exemple produit la sortie suivante :

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

Vous devez parfois transformer des fichiers XML volumineux et écrire votre application de sorte que son encombrement mémoire soit prévisible. Si vous tentez de remplir une arborescence XML avec un très grand fichier XML, l'utilisation de la mémoire sera proportionnelle à la taille du fichier (c'est-à-dire excessive). Par conséquent, vous devez utiliser une technique de diffusion en continu à la place.

Certains opérateurs de requête standard, tels que OrderBy, itèrent au sein de leur source, recueillent toutes les données, les trient, puis produisent le premier élément de la séquence. Notez que si vous utilisez un opérateur de requête qui matérialise sa source avant de produire le premier élément, vous ne conserverez pas un faible encombrement mémoire pour votre application.

Même si vous utilisez la technique décrite dans , si vous essayez d’assembler une arborescence XML qui contient le document transformé, l’utilisation de la mémoire peut être trop importante.

L’exemple suivant s’appuie sur l’exemple de flux de fragments XML avec accès aux informations d’en-tête.

Il utilise les capacités d'exécution différée de XStreamingElement pour diffuser la sortie en continu.

Notez que l'axe personnalisé (StreamCustomerItem) est spécifiquement écrit de sorte qu'il s'attende à recevoir un document possédant des éléments Customer, Name et Item, et que ces éléments seront disposés comme dans le document Source.xml suivant. Une implémentation plus robuste, toutefois, validerait le document source avec un fichier XSD ou serait préparée à analyser un document non valide.

Voici le document source, 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>  

Le code suivant contient une méthode qui utilise un XmlReader flux de données XML source. Il utilise XStreamingElement pour diffuser en continu le nouveau 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  

Cet exemple produit la sortie suivante :

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

Remarques

Cette classe vous permet de créer une arborescence XML qui prend en charge la sortie de streaming différée. Vous utilisez cette classe pour créer une arborescence XML de manière très similaire à la création d’une arborescence XML à l’aide XElementde . Toutefois, il existe une différence fondamentale. Lorsque vous utilisez une requête LINQ pour spécifier du contenu lors de la création d’une arborescence XML à l’aide XElementde , la variable de requête est itérée au moment de la construction de l’arborescence XML et les résultats de la requête sont ajoutés à l’arborescence XML. En revanche, lorsque vous créez une arborescence XML à l’aide XStreamingElementde , une référence à la variable de requête est stockée dans l’arborescence XML sans être itérée. Les requêtes sont itérées uniquement lors de la sérialisation. Cela vous permet de créer des arborescences XML plus volumineuses tout en conservant un encombrement mémoire plus faible.

Si vous diffusez en continu à partir d’une source d’entrée, comme un fichier texte, vous pouvez lire un fichier texte très volumineux et générer un document XML très volumineux tout en conservant un faible encombrement mémoire.

Un autre scénario est que vous disposez d’une grande arborescence XML chargée en mémoire et que vous souhaitez créer une version transformée du document. Si vous créez un document à l’aide XElementde , vous aurez deux arborescences XML volumineuses en mémoire à la fin de la transformation. Toutefois, si vous créez l’arborescence XML à l’aide XStreamingElementde , votre jeu de travail sera réduit de moitié.

Notez que lors du débogage d’un programme qui utilise XStreamingElement, l’affichage de la valeur d’un objet entraîne l’appel de sa ToString méthode. Cela entraîne la sérialisation du code XML. Si la sémantique de votre requête d’élément de diffusion en continu est telle que l’élément de streaming ne peut être diffusé qu’une seule fois, cela peut entraîner un comportement indésirable dans votre expérience de débogage.

Constructeurs

XStreamingElement(XName)

Initialise une nouvelle instance de la classe XElement à partir du XName spécifié.

XStreamingElement(XName, Object)

Initialise une nouvelle instance de la classe XStreamingElement avec le nom et le contenu spécifiés.

XStreamingElement(XName, Object[])

Initialise une nouvelle instance de la classe XStreamingElement avec le nom et le contenu spécifiés.

Propriétés

Name

Obtient ou définit le nom de cet élément de diffusion en continu.

Méthodes

Add(Object)

Ajoute le contenu spécifié en tant qu'enfants à ce XStreamingElement.

Add(Object[])

Ajoute le contenu spécifié en tant qu'enfants à ce XStreamingElement.

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.

(Hérité de Object)
GetHashCode()

Fait office de fonction de hachage par défaut.

(Hérité de Object)
GetType()

Obtient le Type de l'instance actuelle.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Object actuel.

(Hérité de Object)
Save(Stream)

Renvoie ce XStreamingElement vers le Stream spécifié.

Save(Stream, SaveOptions)

Génère ce XStreamingElement vers le Stream spécifié, en précisant le cas échéant le comportement de mise en forme.

Save(String)

Sérialiser cet élément de diffusion en continu vers un fichier.

Save(String, SaveOptions)

Sérialiser cet élément de diffusion en continu vers un fichier, en désactivant éventuellement la mise en forme.

Save(TextWriter)

Sérialiser cet élément de diffusion en continu vers un TextWriter.

Save(TextWriter, SaveOptions)

Sérialiser cet élément de diffusion en continu vers un TextWriter, en désactivant éventuellement la mise en forme.

Save(XmlWriter)

Sérialiser cet élément de diffusion en continu vers un XmlWriter.

ToString()

Retourne le code XML mis en forme (en retrait) pour cet élément de diffusion en continu.

ToString(SaveOptions)

Retourne le code XML pour cet élément de diffusion en continu, en désactivant éventuellement la mise en forme.

WriteTo(XmlWriter)

Écrit cet élément de diffusion en continu vers un XmlWriter.

S’applique à

Voir aussi