viernes, 5 de diciembre de 2025

LINQ: consultando documentos XML

Como vimos en la entrega anterior LINQ nos permite realizar consultas de una base de datos o archivos XML.

Suponiendo que tenemos un documento XML (empleado.xml) con el siguiente contenido:

<?xml version="1.0" encoding="UTF-8"?>
<Empleados>
<Empleado> 
<Id>4392552</Id>
<Nombre>Horacio</Nombre>
<Apellidos>Gomez Torres</Apellidos>
<Correo>horacio.gomez.tor@infotec.com</Correo>
<Salario>25000.00</Salario>
<Departamento>202</Departamento>
</Empleado>

<Empleado>
<Id>4292856</Id>
<Nombre>Veronica</Nombre>
<Apellidos>Uribe Gomora</Apellidos>
<Correo>veronica.uribe.gom@infotec.com</Correo>
<Salario>30000.00</Salario>
<Departamento>204</Departamento>
</Empleado>


<Empleado>
<Id>4701330</Id>
<Nombre>Karla</Nombre>
<Apellidos>Perez Perez</Apellidos>
<Correo>karla.perez.per@infotec.com</Correo>
<Salario>28000.00</Salario>
<Departamento>200</Departamento>
</Empleado>

</Empleados>

Lo que sigue es la creación de un proyecto .NET que nos permita leer ese documento y hacer consultas:

1. Creamos un nuevo proyecto con dotnet:

$ dotnet new console -n DemoLinqXml
$ cd DemoLinqXml

El documento XML (empleados.xml) debe estar en la misma ruta del proyecto. Ahora abrimos el programa principal Program.cs y lo editamos:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {
        XDocument doc = XDocument.Load("empleados.xml");

        var empleados = doc.Root.Elements("Empleado");

        // Aquí vamos a incluir las consultas
    }
}

Podríamos obtener todos los datos (como un SELECT):

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {

        try
        {
            XDocument doc = XDocument.Load("empleados.xml");
            var empleados = doc.Root.Elements("Empleado");

            if (empleados != null)
            {
                Console.WriteLine("\t Obtener todos los empleados:");
                var todos = empleados.Select(e => new
                {
                    Id = (int)e.Element("Id"),
                    Nombre = (string)e.Element("Nombre"),
                    Apellidos = (string)e.Element("Apellidos"),
                    Correo = (string)e.Element("Correo"),
                    Salario = (decimal)e.Element("Salario"),
                    Departamento = (int)e.Element("Departamento")
                });

                foreach (var emp in todos)
                {
                    Console.WriteLine($"ID: {emp.Id}");
                    Console.WriteLine($"Nombre: {emp.Nombre} {emp.Apellidos}");
                    Console.WriteLine($"Correo: {emp.Correo}");
                    Console.WriteLine($"Salario: {emp.Salario}");
                    Console.WriteLine($"Departamento: {emp.Departamento}");
                    Console.WriteLine("-------------------------");
                }                

            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("El archivo no existe: {0}", ex.Message);
        }

    }
}

Si queremos obtener solo nombre y correo:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {

        try
        {
            XDocument doc = XDocument.Load("empleados.xml");
            var empleados = doc.Root.Elements("Empleado");

            if (empleados != null)
            {
               
                
                Console.WriteLine("\t Obtener solo nombre y correo:");
                var contactos = empleados
                .Select(e => new
                {
                    Nombre = (string)e.Element("Nombre"),
                    Correo = (string)e.Element("Correo")
                });
                foreach (var contacto in contactos)
                {
                    Console.WriteLine($"{contacto.Nombre} : {contacto.Correo}");
                }

            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("El archivo no existe: {0}", ex.Message);
        }

    }
}

Obtener el empleado que gana más:

Console.WriteLine("\t Obtener el empleado que gana mas:");
var top = empleados.OrderByDescending(e => (decimal)e.Element("Salario")).First();
Console.WriteLine($"El mayor salario es: \n{top} ");

Obtener todos los empleados que ganen mas de $26000.00 (usando una sintaxis similar a SQL):

Console.WriteLine("\t Obtener todos los empleados que ganen mas de $26000.00:");
var query = from e in empleados
                            where (decimal)e.Element("Salario") > 26000
                            orderby (string)e.Element("Nombre")
                            select new
                            {
                                Nombre = (string)e.Element("Nombre"),
                                Salario = (decimal)e.Element("Salario")
                            };

foreach (var emp in query)
{
  Console.WriteLine($"{emp.Nombre} - {emp.Salario:C}");                
}

Obtener empleado del departamento 202:

Console.WriteLine("\t Obtener empleado del departamento 202:");
var depto202 = empleados.Where(e => (int)e.Element("Departamento") == 202);

foreach (var emp in depto202)
{
   Console.WriteLine($"ID: {(int)emp.Element("Id")}");
   Console.WriteLine($"Nombre: {(string)emp.Element("Nombre")}");
   Console.WriteLine($"Apellidos: {(string)emp.Element("Apellidos")}");
   Console.WriteLine($"Correo: {(string)emp.Element("Correo")}");
   Console.WriteLine($"Salario: {(decimal)emp.Element("Salario")}");
   Console.WriteLine($"Departamento: {(int)emp.Element("Departamento")}");
   Console.WriteLine("-------------------------");
}

Código completo:

using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    static void Main()
    {

        try
        {
            XDocument doc = XDocument.Load("empleados.xml");
            var empleados = doc.Root.Elements("Empleado");

            if (empleados != null)
            {
                Console.WriteLine("\t Obtener todos los empleados:");
                var todos = empleados.Select(e => new
                {
                    Id = (int)e.Element("Id"),
                    Nombre = (string)e.Element("Nombre"),
                    Apellidos = (string)e.Element("Apellidos"),
                    Correo = (string)e.Element("Correo"),
                    Salario = (decimal)e.Element("Salario"),
                    Departamento = (int)e.Element("Departamento")
                });

                foreach (var emp in todos)
                {
                    Console.WriteLine($"ID: {emp.Id}");
                    Console.WriteLine($"Nombre: {emp.Nombre} {emp.Apellidos}");
                    Console.WriteLine($"Correo: {emp.Correo}");
                    Console.WriteLine($"Salario: {emp.Salario}");
                    Console.WriteLine($"Departamento: {emp.Departamento}");
                    Console.WriteLine("-------------------------");
                }
                
                Console.WriteLine("\t Obtener solo nombre y correo:");
                var contactos = empleados
                .Select(e => new
                {
                    Nombre = (string)e.Element("Nombre"),
                    Correo = (string)e.Element("Correo")
                });
                foreach (var contacto in contactos)
                {
                    Console.WriteLine($"{contacto.Nombre} : {contacto.Correo}");
                }

                Console.WriteLine("\t Obtener el empleado que gana mas:");
                var top = empleados.OrderByDescending(e => (decimal)e.Element("Salario")).First();
                Console.WriteLine($"El mayor salario es: \n{top} ");

                Console.WriteLine("\t Obtener todos los empleados que ganen mas de $26000.00:");
                var query = from e in empleados
                            where (decimal)e.Element("Salario") > 26000
                            orderby (string)e.Element("Nombre")
                            select new
                            {
                                Nombre = (string)e.Element("Nombre"),
                                Salario = (decimal)e.Element("Salario")
                            };

                foreach (var emp in query)
                {
                    Console.WriteLine($"{emp.Nombre} - {emp.Salario:C}");
                }


                Console.WriteLine("\t Obtener empleado del departamento 202:");
                var depto202 = empleados.Where(e => (int)e.Element("Departamento") == 202);
                foreach (var emp in depto202)
                {
                    Console.WriteLine($"ID: {(int)emp.Element("Id")}");
                    Console.WriteLine($"Nombre: {(string)emp.Element("Nombre")}");
                    Console.WriteLine($"Apellidos: {(string)emp.Element("Apellidos")}");
                    Console.WriteLine($"Correo: {(string)emp.Element("Correo")}");
                    Console.WriteLine($"Salario: {(decimal)emp.Element("Salario")}");
                    Console.WriteLine($"Departamento: {(int)emp.Element("Departamento")}");
                    Console.WriteLine("-------------------------");
                }

            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine("El archivo no existe: {0}", ex.Message);
        }

    }
}

Ejecutamos el código:

$ dotnet run

Salida:

         Obtener todos los empleados:
ID: 4392552
Nombre: Horacio Gomez Torres
Correo: horacio.gomez.tor@infotec.com
Salario: 25000.00
Departamento: 202
-------------------------
ID: 4292856
Nombre: Veronica Uribe Gomora
Correo: veronica.uribe.gom@infotec.com
Salario: 30000.00
Departamento: 204
-------------------------
ID: 4701330
Nombre: Karla Perez Perez
Correo: karla.perez.per@infotec.com
Salario: 28000.00
Departamento: 200
-------------------------
         Obtener solo nombre y correo:
Horacio : horacio.gomez.tor@infotec.com
Veronica : veronica.uribe.gom@infotec.com
Karla : karla.perez.per@infotec.com
         Obtener el empleado que gana mas:
El mayor salario es:
<Empleado>
  <Id>4292856</Id>
  <Nombre>Veronica</Nombre>
  <Apellidos>Uribe Gomora</Apellidos>
  <Correo>veronica.uribe.gom@infotec.com</Correo>
  <Salario>30000.00</Salario>
  <Departamento>204</Departamento>
</Empleado>
         Obtener todos los empleados que ganen mas de $26000.00:
Karla - $28,000.00
Veronica - $30,000.00
         Obtener empleado del departamento 202:
ID: 4392552
Nombre: Horacio
Apellidos: Gomez Torres
Correo: horacio.gomez.tor@infotec.com
Salario: 25000.00
Departamento: 202
-------------------------

Ventajas y desventajas de usar LINQ for XML

Aquí una pequeña tabla con las ventajas y desventajas del uso de LINQ para leer documentos XML.

Aspecto Ventajas Desventajas
Rendimiento Rápido para XML pequeños o medianos No apto para XML muy grandes (carga completa en memoria)
Legibilidad Sintaxis clara, declarativa y fácil de mantener Puede ser más verboso que XPath en consultas profundas
Tipado Conversión automática a tipos C# Puede lanzar excepciones si faltan nodos o tipos incorrectos
Flexibilidad Fácil de combinar con otras colecciones LINQ Menos eficiente para búsquedas complejas o profundas
Portabilidad Integrado y natural en .NET No es estándar fuera del ecosistema .NET

Seguiremos con esta serie sobre tecnología .NET y C#.

Enlaces:

https://codemonkeyjunior.blogspot.com/2025/11/linq-un-lenguaje-de-consulta-para-c.html
https://learn.microsoft.com/es-es/dotnet/standard/linq/linq-xml-overview

No hay comentarios:

Publicar un comentario

LINQ: consultando documentos XML

Como vimos en la entrega anterior LINQ nos permite realizar consultas de una base de datos o archivos XML. Suponiendo que tenemos un...

Etiquetas

Archivo del blog