Crear árboles XML en C# (LINQ to XML)
En esta sección encontrará información acerca de cómo crear árboles XML en C#.
Para obtener información acerca de cómo utilizar los resultados de las consultas LINQ como contenido para un XElement, vea Construcción funcional (LINQ to XML).
Elementos de construcción
Las firmas de los constructores XElement y XAttribute le permiten pasar los contenidos del elemento o atributo como argumentos del constructor. Dado que uno de los constructores recibe un número variable de argumentos, podrá pasar tantos elementos secundarios como desee. Por supuesto, cada uno de esos elementos secundarios podrá contener sus propios elementos secundarios. Para cualquier elemento, podrá agregar cuantos atributos desee.
Cuando se agregan objetos XNode (incluyendo el objeto XElement) o XAttribute, si el contenido nuevo no tiene un elemento primario, los objetos simplemente se adjuntan al árbol XML. Si el contenido nuevo ya tiene un elemento primario y forma parte de otro árbol XML, el nuevo contenido se clonará y ese clon se adjuntará al árbol XML. El último ejemplo de este tema muestra este comportamiento.
Para crear un contacts XElement, podría utilizar el siguiente código:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Si se aplica correctamente la sangría, el código que construye los objetos XElement se asemeja mucho a la estructura del contenido XML subyacente.
Visual Basic ofrece otra alternativa a la hora de crear árboles XML: es posible incrustar directamente datos XML en el programa de Visual Basic como un literal XML. Para obtener más información, vea Introducción a los literales XML en Visual Basic.
Constructores de XElement
La clase XElement utiliza los siguientes constructores para llevar a cabo una construcción funcional. Observe que existen algunos constructores más para XElement, pero, dado que no se utilizan para el proceso de construcción funcional, no se detallarán aquí.
Constructor |
Descripción |
---|---|
XElement(XName name, object content) |
Crea un XElement. El parámetro name especifica el nombre del elemento; content especifica el contenido del elemento. |
XElement(XName name) |
Crea un XElement cuyo XName se inicializa con el nombre especificado. |
XElement(XName name, params object[] content) |
Crea un XElement cuyo XName se inicializa con el nombre especificado. Los atributos y/o elementos secundarios se crean a partir de los contenidos de la lista de parámetros. |
El parámetro content es extremadamente flexible. Admite cualquier tipo de objeto que sea un elemento secundario válido de un XElement. Se aplicarán las siguientes reglas a los diferentes tipos de objetos pasados en este parámetros:
Una cadena se agrega como contenido de tipo texto.
Un XElement se agrega como un elemento secundario.
Un XAttribute se agrega como un atributo.
Un XProcessingInstruction, XComment o un XText se agregan como un contenido secundario.
Un IEnumerable es un tipo enumerado y se aplicarán estas reglas recursivamente a los resultados.
Para el resto de tipos, se llamará a su método ToString y se agregará el resultado como contenido de tipo texto.
Crear un XElement con contenidos
Puede crear un XElement que contenga un contenido simple con una única llamada a método. Para ello, especifique el contenido como segundo parámetro, tal y como sigue:
XElement n = new XElement("Customer", "Adventure Works");
Console.WriteLine(n);
Este ejemplo genera el siguiente resultado:
<Customer>Adventure Works</Customer>
Puede pasar cualquier tipo de objeto como contenido. Por ejemplo, el siguiente código crea un elemento que contiene un número de punto flotante como contenido:
XElement n = new XElement("Cost", 324.50);
Console.WriteLine(n);
Este ejemplo genera el siguiente resultado:
<Cost>324.5</Cost>
Al número de punto flotante se le aplica la conversión boxing y se pasa al constructor. El número se convierte entonces en una cadena y se utiliza como contenido del elemento.
Crear un XElement con un elemento secundario
Si pasa una instancia de la clase XElement para el argumento del contenido, el constructor creará un elemento que tiene un elemento secundario:
XElement shippingUnit = new XElement("ShippingUnit",
new XElement("Cost", 324.50)
);
Console.WriteLine(shippingUnit);
Este ejemplo genera el siguiente resultado:
<ShippingUnit>
<Cost>324.5</Cost>
</ShippingUnit>
Crear un XElement con varios elementos secundarios
Para el contenido, puede pasar tantos objetos XElement como desee. Cada uno de los objetos XElement se incluye como elemento secundario.
XElement address = new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
);
Console.WriteLine(address);
Este ejemplo genera el siguiente resultado:
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
Si se extiende el ejemplo anterior, es posible crear un árbol XML completo, tal y como sigue:
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Console.WriteLine(contacts);
Este ejemplo genera el siguiente resultado:
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
Crear un elemento vacío
Para crear un XElement vacío, no pase ningún contenido al constructor. El siguiente ejemplo crea un elemento vacío:
XElement n = new XElement("Customer");
Console.WriteLine(n);
Este ejemplo genera el siguiente resultado:
<Customer />
Diferencias entre adjuntar yclonar
Como mencionamos anteriormente, cuando se agregan objetos XNode (incluyendo el objeto XElement) o XAttribute, si el contenido nuevo no tiene un elemento primario, los objetos simplemente se adjuntan al árbol XML. Si el contenido nuevo ya tiene un elemento primario y forma parte de otro árbol XML, el nuevo contenido se clonará y ese clon se adjuntará al árbol XML.
// Create a tree with a child element.
XElement xmlTree1 = new XElement("Root",
new XElement("Child1", 1)
);
// Create an element that is not parented.
XElement child2 = new XElement("Child2", 2);
// Create a tree and add Child1 and Child2 to it.
XElement xmlTree2 = new XElement("Root",
xmlTree1.Element("Child1"),
child2
);
// Compare Child1 identity.
Console.WriteLine("Child1 was {0}",
xmlTree1.Element("Child1") == xmlTree2.Element("Child1") ?
"attached" : "cloned");
// Compare Child2 identity.
Console.WriteLine("Child2 was {0}",
child2 == xmlTree2.Element("Child2") ?
"attached" : "cloned");
Este ejemplo genera el siguiente resultado:
Child1 was cloned
Child2 was attached