Este artículo se tradujo automáticamente. Para ver el artículo en inglés, active la casilla Inglés. Además, puede mostrar el texto en inglés en una ventana emergente si mueve el puntero del mouse sobre el texto.
Traducción
Inglés

Clase XStreamingElement

 

Publicado: noviembre de 2016

Representa los elementos de un árbol XML que admite la salida de transmisión por secuencias diferida.

Espacio de nombres:   System.Xml.Linq
Ensamblado:  System.Xml.Linq (en System.Xml.Linq.dll)

System.Object
  System.Xml.Linq.XStreamingElement

public class XStreamingElement

NombreDescripción
System_CAPS_pubmethodXStreamingElement(XName)

Inicializa una nueva instancia de la clase XElement a partir del XName especificado.

System_CAPS_pubmethodXStreamingElement(XName, Object)

Inicializa una nueva instancia de la XStreamingElement clase con el nombre especificado y el contenido.

System_CAPS_pubmethodXStreamingElement(XName, Object[])

Inicializa una nueva instancia de la XStreamingElement clase con el nombre especificado y el contenido.

NombreDescripción
System_CAPS_pubpropertyName

Obtiene o establece el nombre de este elemento de transmisión por secuencias.

NombreDescripción
System_CAPS_pubmethodAdd(Object)

Agrega el contenido especificado como elementos secundarios a este XStreamingElement.

System_CAPS_pubmethodAdd(Object[])

Agrega el contenido especificado como elementos secundarios a este XStreamingElement.

System_CAPS_pubmethodEquals(Object)

Determina si el objeto especificado es igual al objeto actual.(Heredado de Object).

System_CAPS_protmethodFinalize()

Permite que un objeto intente liberar recursos y realizar otras operaciones de limpieza antes de ser reclamado por el recolector de basura. (Heredado de Object).

System_CAPS_pubmethodGetHashCode()

Sirve como la función hash predeterminada.(Heredado de Object).

System_CAPS_pubmethodGetType()

Obtiene el Type de la instancia actual.(Heredado de Object).

System_CAPS_protmethodMemberwiseClone()

Crea una copia superficial del Object actual.(Heredado de Object).

System_CAPS_pubmethodSave(Stream)

Genera este XStreamingElement especificado Stream.

System_CAPS_pubmethodSave(Stream, SaveOptions)

Genera este XStreamingElement especificado Stream, especificando opcionalmente el comportamiento de formato.

System_CAPS_pubmethodSave(String)

Serialice este elemento de transmisión por secuencias en un archivo.

System_CAPS_pubmethodSave(String, SaveOptions)

Serialice este elemento de transmisión por secuencias en un archivo, opcionalmente se deshabilita el formato.

System_CAPS_pubmethodSave(TextWriter)

Serialice este elemento de transmisión por secuencias en un TextWriter.

System_CAPS_pubmethodSave(TextWriter, SaveOptions)

Serialice este elemento de transmisión por secuencias en un TextWriter, opcionalmente se deshabilita el formato.

System_CAPS_pubmethodSave(XmlWriter)

Serialice este elemento de transmisión por secuencias en un XmlWriter.

System_CAPS_pubmethodToString()

Devuelve el XML con formato (sangría) para este elemento de transmisión por secuencias.(Invalida Object.ToString()).

System_CAPS_pubmethodToString(SaveOptions)

Devuelve el XML de este elemento de transmisión por secuencias y, opcionalmente, deshabilita el formato.

System_CAPS_pubmethodWriteTo(XmlWriter)

Escribe este elemento de transmisión por secuencias en un XmlWriter.

Esta clase permite crear un árbol XML que admite la salida de transmisión por secuencias diferida. Utilice esta clase para crear un árbol XML en un modo muy similar a la creación de un árbol XML utilizando XElement. Sin embargo, hay una diferencia fundamental. Cuando usa una consulta LINQ para especificar el contenido al crear un árbol XML usando XElement, se recorre en iteración la variable de consulta en el momento de la construcción del árbol XML y los resultados de la consulta se agregan al árbol XML. En cambio, cuando se crea un árbol XML utilizando XStreamingElement, una referencia a la variable de consulta se almacena en el árbol XML sin que se repite. Las consultas se recorren en iteración en la serialización. Esto le permite crear los árboles XML más grandes manteniendo una superficie de memoria menor.

Si está transmitiendo por secuencias desde un origen de entrada, como un archivo de texto, puede leer un archivo de texto muy grandes y generar un documento XML muy grande manteniendo una superficie de memoria pequeña.

Otro escenario es que tiene un árbol XML grande que se han cargado en memoria, y desea crear una versión transformada del documento. Si crea un documento nuevo mediante XElement, tendrá dos árboles XML de gran tamaño en memoria durante la realización de la transformación. Sin embargo, si crea el nuevo árbol XML mediante XStreamingElement, a continuación, se eliminará el espacio de trabajo eficazmente por la mitad.

Tenga en cuenta que, cuando se depura un programa que utiliza XStreamingElement, mostrar el valor de un objeto hace su ToString método al que llamar. Esto hace que el XML que se va a serializar. Si la semántica de la consulta de elemento de transmisión por secuencias es tal que la transmisión por secuencias sólo se puede transmitir una vez, esto puede provocar un comportamiento no deseado en la experiencia de depuración.

En el ejemplo siguiente se crea primero un árbol XML de origen. A continuación, crea una transformación del árbol XML de origen utilizando XElement. Esta transformación crea un nuevo árbol en memoria. A continuación, crea una transformación del árbol XML de origen utilizando XStreamingElement. Esta transformación no ejecuta la consulta hasta que el árbol transformado se serialice en la consola. El uso de memoria es menor.


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

Este ejemplo produce el siguiente resultado:


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

Un enfoque del procesamiento de un archivo de texto es escribir un método de extensión que transmita el archivo de texto por secuencias de línea en línea mediante la construcción yield return. Después, puede escribir una consulta LINQ que procese el archivo de texto de forma aplazada y lenta. Si se utiliza el XStreamingElement para transmitir el resultado, puede crear una transformación del archivo de texto al XML usando una cantidad mínima de memoria, independientemente del tamaño del archivo de texto de origen.

El siguiente archivo de texto, People.txt, es el origen de este ejemplo.


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

El siguiente código contiene un método de extensión que transmite las líneas del archivo de texto por secuencias de forma diferida.


                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();
    }
}

Este ejemplo produce el siguiente resultado:


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

A veces tiene que transformar los archivos XML grandes y escribir la aplicación para que sea predecible la superficie en memoria de la aplicación. Si intenta rellenar un árbol XML con un archivo XML de gran tamaño, su utilización de memoria será proporcional al tamaño del archivo (es decir, excesivo). Por consiguiente, debe utilizar en su lugar una técnica de transmisión por secuencias.

Ciertos operadores de consulta estándar, como OrderBy<TSource, TKey>, recorren en iteración su origen, recaban todos los datos, los ordenan y finalmente producen el primer elemento de la secuencia. Tenga en cuenta que si utiliza un operador de consulta que materializa su origen antes de producir el primer elemento, no retendrá una superficie de memoria pequeña para la aplicación.

Incluso si utiliza la técnica descrita en, si intenta ensamblar un árbol XML que contiene el documento transformado, uso de memoria puede ser demasiado grande.

El ejemplo siguiente se basa en otro de Cómo transmitir por secuencias fragmentos XML con acceso a la información de encabezado.

Este ejemplo utiliza las funciones de ejecución aplazada de XStreamingElement para transmitir por secuencias el resultado.

Observe que se escribe el eje personalizado (StreamCustomerItem) específicamente para que espere un documento que tiene los elementos Customer, Name e Item, y que esos elementos se organizarán como en el documento Source.xml siguiente. Una implementación más sólida, sin embargo, validaría el documento de origen con XSD o se prepararía para analizar un documento no válido.

A continuación, se muestra el documento de origen, 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>

El código siguiente contiene un método que utiliza un XmlReader para transmitir el código fuente XML. Utiliza XStreamingElement para transmitir el nuevo 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"));
}

Este ejemplo produce el siguiente resultado:


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

Plataforma universal de Windows
Disponible desde 8
.NET Framework
Disponible desde 3.5
Biblioteca de clases portable
Se admite en: plataformas portátiles de .NET
Silverlight
Disponible desde 2.0
Windows Phone Silverlight
Disponible desde 7.0
Windows Phone
Disponible desde 8.1

Cualquier miembro ( Compartido en Visual Basic) estático público de este tipo es seguro para subprocesos. No se garantiza que los miembros de instancia sean seguros para subprocesos.

Volver al principio
Mostrar: