Escribir datos XML con LINQ

25. June 2011 03:09 by Oscar.SS in XML  //  Tags: ,   //   Comments (8)

En su día escribí una serie de artículos sobre como leer, escribir, insertar, modificar y borrar datos en archivos XML utilizando algunas de las clases que encontramos en el espacion de nombres System.Xml.

Lo cierto es que esta serie tuvo mucho éxito, tanto en comentarios como en visitas. Aún hoy en día sigue siendo de los más buscados entre las visitas a este blog. Así que me he animado a escribir otra serie, idéntica en concepto a la anterior, pero esta vez manipulando los archivos XML con LINQ.

En este primer artículo vamos a ver como escribir un documento XML completo utilizando LINQ y las clases que encontraremos como es lógico en el espacio de nombres System.Xml.Linq. En concreto utilizaremos 3 únicas clases:

  • XDocument. Representa el documento XML.
  • XDeclaration. Contiene información relativa a la declaración del document XML.
  • XElement. Representa un nodo del documento. Este nodo puede ser el nodo raiz, un nodo hijo o cualquier nodo anidado en el documento.

Antes de ver el código de ejemplo, comentaros que la estructura del documento XML que vamos a tratar en toda la serie de artículos es el mismo que en la serie anterior.

¡Sin más preámbulos el código!

        static void EscribirXml()
        {
            
//Declaramos el documento y su definición
            
XDocument document = new XDocument(
                
new XDeclaration("1.0""utf-8"null));

            
//Creamos el nodo raiz y lo añadimos al documento
            
XElement nodoRaiz = new XElement("empleados");
            
document.Add(nodoRaiz);

            for 
(int 1i <5i++)
            {
                
//Creamos el nodo empleado y el contenido con sus nodos hijos
                
XElement nodoEmpleado = new XElement("empleado");
                
nodoEmpleado.Add(new XElement("idEmpleado", i));
                
nodoEmpleado.Add(new XElement("nombre""UnNombre" + i));
                
nodoEmpleado.Add(new XElement("apellidos""UnosApellidos" + i));
                
nodoEmpleado.Add(new XElement("numeroSS""111-111-11" + i));
                
nodoEmpleado.Add(new XElement("telefonos",
                                            
new XElement("fijo""90000000" + i),
                                            
new XElement("movil""60000000" + i)));

                
//Añadirmos el nodo empleado y escribimos en el documento
                
nodoRaiz.Add(nodoEmpleado);   
            
}

            document.Save(xmlPath)
;
        
}

 

Como podemos apreciar es mucho más sencillo que el ejemplo "antiguo" y sobre todo más intuitivo y elegante. Llamaros la atención únicamente sobre la clase XElement que admite un segundo parámetro de tipo params object[] que nos permite ir anidando directa y sucesivamente los nodos hijos que necesitemos. Como en el ejemplo los dos nodos correspondientes a los teléfonos del empleado.

El resultado obtenido al ejecutar este método sería el siguiente.

<?xml version="1.0" encoding="utf-8"?>
<empleados>
  
<empleado>
    
<idEmpleado>1</idEmpleado>
    
<nombre>UnNombre1</nombre>
    
<apellidos>UnosApellidos1</apellidos>
    
<numeroSS>111-111-111</numeroSS>
    
<telefonos>
      
<fijo>900000001</fijo>
      
<movil>600000001</movil>
    
</telefonos>
  
</empleado>
  
<empleado>
    
<idEmpleado>2</idEmpleado>
    
<nombre>UnNombre2</nombre>
    
<apellidos>UnosApellidos2</apellidos>
    
<numeroSS>111-111-112</numeroSS>
    
<telefonos>
      
<fijo>900000002</fijo>
      
<movil>600000002</movil>
    
</telefonos>
  
</empleado>
  
<empleado>
    
<idEmpleado>3</idEmpleado>
    
<nombre>UnNombre3</nombre>
    
<apellidos>UnosApellidos3</apellidos>
    
<numeroSS>111-111-113</numeroSS>
    
<telefonos>
      
<fijo>900000003</fijo>
      
<movil>600000003</movil>
    
</telefonos>
  
</empleado>
  
<empleado>
    
<idEmpleado>4</idEmpleado>
    
<nombre>UnNombre4</nombre>
    
<apellidos>UnosApellidos4</apellidos>
    
<numeroSS>111-111-114</numeroSS>
    
<telefonos>
      
<fijo>900000004</fijo>
      
<movil>600000004</movil>
    
</telefonos>
  
</empleado>
  
<empleado>
    
<idEmpleado>5</idEmpleado>
    
<nombre>UnNombre5</nombre>
    
<apellidos>UnosApellidos5</apellidos>
    
<numeroSS>111-111-115</numeroSS>
    
<telefonos>
      
<fijo>900000005</fijo>
      
<movil>600000005</movil>
    
</telefonos>
  
</empleado>
</empleados> 

Comments (8) -

froylan
froylan
11/22/2011 7:14:07 PM #

hola me gustan mucho tus tutos, me gustaria saber si tienes esto en version sitioweb c#, esque tengo una tarea y no se bien como se hace!!

gracias!

Óscar.SS
Óscar.SS
11/22/2011 7:24:37 PM #

Hola Froylan, lo siento pero no he entendido que es lo que necesitas. Por favor, mira si puedes especificar un poco más y te puedo ayudar.

Un saludo.

froylan
froylan
11/22/2011 9:32:48 PM #

el caso es que tengo que hacer un sistema web que registre a un empleado a través de un webform y el formulario se guarde en un documento  xml y tener la posibilidad de insertar mas empleados en el mismo documento xml!

froylan
froylan
11/22/2011 10:41:33 PM #

la cosa es que necesito hacer esto solo que en un sitio web c# con webform! y que los form se guarden en el xml con la opcion de agregar otro registro!

Oscar.SS
Oscar.SS
11/23/2011 12:33:10 AM #

Hola Froylan:

La verdad es que tengo pendiente continuar con la serie de ejemplos de como manejar XML con Linq pero de momento me falta tiempo. Por si te sirve de ayuda también puedes insertar nuevos registros con las clases de System.Xml, puedes ver un ejemplo en:

oscarsotorrio.com/.../Insertar-datos-XML.aspx

Si prefieres hacerlo con Linq quizás te sirva esto:

www.aspnettutorials.com/.../...-xml-adding-cs.aspx

Y para información ampliada siempre puedes consultar la documentación oficial:

msdn.microsoft.com/en-us/library/bb308960.aspx

Espero que esto te sirva de ayuda.

Un saludo

froylan
froylan
11/23/2011 1:06:09 AM #

e estado trabajandolo con uno de sus codigos y tengo esto

XmlDocument documento = new XmlDocument();
        documento.Load(@"c:\datos\documento.xml");

        //Creamos el nodo que deseamos insertar.
        XmlElement empleado = documento.CreateElement("empleado");

        //Creamos el elemento idEmpleado.
        XmlElement idEmpleado = documento.CreateElement("idEmpleado");
        idEmpleado.InnerText = id;
        empleado.AppendChild(idEmpleado);

        //Creamos el elemento nombre.
        XmlElement nombre = documento.CreateElement("nombre");
        nombre.InnerText = nom;
        empleado.AppendChild(nombre);

        //Creamos el elemento apellidos.
        XmlElement apellidos = documento.CreateElement("apellidos");
        apellidos.InnerText = ape;
        empleado.AppendChild(apellidos);

        //Creamos el elemento numeroSS.
        XmlElement numeroSS = documento.CreateElement("fecha_nac");
        numeroSS.InnerText = fecha;
        empleado.AppendChild(numeroSS);

        //Creamos el elemento telefonos.
        XmlElement telefonos = documento.CreateElement("telefonos");
        telefonos.InnerText = tel;
        empleado.AppendChild(telefonos);

        //Creamos el elemento telefonos.
        XmlElement email = documento.CreateElement("email");
        email.InnerText = mail;
        empleado.AppendChild(email);

        //Creamos el elemento movil.
        XmlElement direccion = documento.CreateElement("direccion");
        direccion.InnerText = direc;
        telefonos.AppendChild(direccion);

        return empleado;
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
    
    protected void Button1_Click(object sender, EventArgs e)
    {
      
        for (int i = 1; i <8; i++)
        {
            //Cargamos el documento XML.
            XmlDocument documento = new XmlDocument();
            documento.Load(@"c:\datos\documento.xml");

            //Creamos el nodo que deseamos insertar.
            XmlNode empleado = this.CrearNodoXml(TextBox1.Text, TextBox2.Text,TextBox4.Text,TextBox5.Text,TextBox6.Text,TextBox7.Text);

            //Obtenemos el nodo raiz del documento.
            XmlNode nodoRaiz = documento.DocumentElement;

            //Insertamos el nodo empleado al final del archivo
            nodoRaiz.InsertAfter(empleado, nodoRaiz.LastChild);   //***

            documento.Save(@"c:\datos\documento.xml");

        }

        TextBox1.Text = "";
        TextBox2.Text = "";
        TextBox4.Text = "";
        TextBox5.Text = "";
        TextBox6.Text = "";
        TextBox7.Text = "";


    }
}

y me da el siguiente error


Error  3  Ninguna sobrecarga para el método 'CrearNodoXml' toma '6' argumentos  C:\Users\froy\Desktop\sistema\Default.aspx.cs  73  32  C:\...\sistema\

froylan
froylan
11/23/2011 1:37:51 AM #

al resolver ese error me da otro que dice que me falta el elemento raiz  al momento de cargar el documento xml

Oscar.SS
Oscar.SS
11/23/2011 8:18:07 AM #

Hola de nuevo Froylan:

Sin probar el código ya que te escribo desde un dispositivo móvil creo que sé cual es el error.

Fíjate que tienes 2 instancias en memoria del mismo documento XML. Es decir, dentro del método CrearNodoXml() creas una variable local a este método llamada "documento" donde guardas la instancia del XML. Y luego, en el evento click del botón creas una nueva variable donde almacenas una nueva instancia del mismo documento XML.

Vamos, que lo que sucede es que primero construyes el nodo para una instancia del documento en memoria y luego intentas insertar este nodo para otra instancia en memoria distinta.

La solución es poner la definición de XmlDocument documento = new XmlDocument(); a nivel de clase y tanto desde el método como desde el evento hacer referencia a esta única variable que contendrá una única instancia de tu documento XML.

Pruébalo y nos comentas!!

Un saludo

Recent Comments

Comment RSS

Month List