Mostrando entradas con la etiqueta xml. Mostrar todas las entradas
Mostrando entradas con la etiqueta xml. Mostrar todas las entradas

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

sábado, 12 de noviembre de 2011

¿XML ... eso con que se come?



Java aparte de bonito, barato y eficiente es un lenguaje que permite procesar (con ayuda de algunas herramientas como:JAXB , XStream, JDom, etc.) los archivos *.xml.
Los documentos xml tienen varios usos:
  1. Intercambo de informaciön entre aplicaciones (Web o de escritorio)
  2. XML como "base de datos"
  3. Ahorro de recursos de los servidores
  4. etc.
Permite crear etiquetas personalizadas, sin embargo, es necesario que los documentos xml tengan un significado coherente.
Un ejemplo. Crear un xml que represente la entidad Programador y sus atributos (nombre,edad y email).
Programador.xml
<?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>
<Programador>
<Nombre>Daniel</Nombre>
<Edad>27</Edad>
<Email>daniel.2132@servidor.com</Email>
</Programador>
Es un archivo xml básico, pero todavia falta como darle validez.

¿Cómo se le da validez a los archivos xml?

Existen dos alternativas (validadores) los Documentos de definición de tipos:
1. DTD : ,describe la estructura del documento con un lenguaje que no tiene nada que ver con XML.
2. XML Schemas: describe la estructura con XML
Ejemplo con DTD.
programador.dtd
<!ELEMENT Programador(Nombre,Edad,Email)>
<!ELEMENT Nombre (#PCDATA)>
<!ELEMENT Edad (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
Existen reglas para definir los elementos ( ), la cardinalidad (?,*,+), pero solo quiero poner una muestra sencilla.
Asi quedaria el documento xml con dtd.
<?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>
<!DOCTYPE Programador SYSTEM "programador.dtd">
<Programador>
<Nombre>Daniel</Nombre>
<Edad>27</Edad>
<Email>daniel.2132@servidor.com</Email>
</Programador>

Tratamiento de documentos XML

Básicamente existen dos alternativas (se denominan parsers o analizadores):
1. SAX:Simple API for XML, consiste en procesar los documentos xml según se va leyendo las etiquetas y se van localzando los elementos
2. DOM:Document Object Model, consiste en leer el documento xml y obtener y modelo basado en objetos que se mantienene en memoria para poder realizar el tratamiento conforme sea necesario sobe la información leida. Es más lento que SAX.


He aqui un ejemplo de un programa que lee XML escrito por @javadabadoo


Espero continuar con el tema y hacer un ejemplo con JAXB. En otro post trataréde hablar más de esa tecnología con ayuda de NetBeans y/o Eclipse.





JAXB
Crear una clase java básica.
Datos1.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package modelo.pruebas;
//import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
 *
 * @author yo
 */
@XmlRootElement
public class Datos1 {
   
    private double valor,tasa;
    private int periodo;     /**
     * @return the valor
     */
    public double getValor() {
        return valor;
    }
    /**
     * @param valor the valor to set
     */
    @XmlElement
    public void setValor(double valor) {
        this.valor = valor;
    }
    /**
     * @return the tasa
     */
    public double getTasa() {
        return tasa;
    }
    /**
     * @param tasa the tasa to set
     */
    @XmlElement
    public void setTasa(double tasa) {
        this.tasa = tasa;
    }
    /**
     * @return the periodo
     */
    public int getPeriodo() {
        return periodo;
    }
    /**
     * @param periodo the periodo to set
     */
    @XmlElement
    public void setPeriodo(int periodo) {
        this.periodo = periodo;
    }
   
   
}
Convertir esa clase a xml.
ControlDatos1Xml.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control.pruebas; import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import modelo.pruebas.Datos1;
import javax.swing.JOptionPane;
/**
 *
 * @author yo
 */
public class ControlDatos1Xml {
   
    Datos1 datos= new Datos1();
    public static void main(String[] args){
         ControlDatos1Xml control= new ControlDatos1Xml();
       
         double v=0,t=0; int p;
         v=Double.parseDouble(JOptionPane.showInputDialog("valor"));
         t=Double.parseDouble(JOptionPane.showInputDialog("tasa"));
         p=Integer.parseInt(JOptionPane.showInputDialog("periodo"));
       
       
         control.datos.setPeriodo(p);
         control.datos.setTasa(t);
         control.datos.setValor(v);
       
         //------------------------------------
         try {

                File file = new File("/home/user/PruebasClases/dat1.xml");
                JAXBContext jaxbContext = JAXBContext.newInstance(Datos1.class);
                Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

               
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                jaxbMarshaller.marshal(control.datos, file);
                jaxbMarshaller.marshal(control.datos, System.out);

              } catch (JAXBException e) {
                e.printStackTrace();
              }
       
         JOptionPane.showMessageDialog(null, "XML generado");
       
        //-----------------------------------
   
       
       
     
    }
   
   
   
}
Leer el XML como si fuera objeto.
ControlDatos1Class.java
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package control.pruebas;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import modelo.pruebas.Datos1; /**
 *
 * @author yo
 */
public class ControlDatos1Class {
    public static void main(String[] args){
       
        try {

                File file = new File("/home/user/PruebasClases/dat1.xml");
                JAXBContext jaxbContext = JAXBContext.newInstance(Datos1.class);

                Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
                Datos1 datos = (Datos1) jaxbUnmarshaller.unmarshal(file);
                System.out.println(datos);
               
               
                //---------------------------------------
                if(datos.getValor()<=0){
                  System.out.println("El valor no debe ser menor o igual a cero");
                }
               
                //------------------------------------
               
                else{
                System.out.println("valor -->"+datos.getValor());
               
               
                System.out.println("tasa -->"+datos.getTasa());
                System.out.println("periodo -->"+datos.getPeriodo());
                }

          } catch (JAXBException e) {
                e.printStackTrace();
          }
       
        //-----------------------------------
       
   
    }
   
}



JAXB

Es una tecnología que permite obtener una representación XML de un objeto Java y viceversa.

Algunas librerías necesarias para trabajar con JAXB:

javax.xml.bind.JAXBContext
javax.xml.bind.JAXBException
javax.xml.bind.Mashaller
javax.xml.bind.Unmashaller
javax.xml.bind.annotation.XmlAttribute
javax.xml.bind.annotation.XmlRootElement
javax.xml.bind.annotation.XmlElement
javax.xml.bind.annotation.XmlType
javax.xml.bind.annotation.XmlAccessType
javax.xml.bind.annotation.XmlAccessorType
javax.xml.bind.annotation.XmlEnumValue
javax.xml.bind.annotation.XmlList
javax.xml.bind.annotation.XmlElementWrapper


XML … XML Schemas

XML Schemas (*.xsd): Se tratan de documentos XML que permiten definir la estructura y validez de documentos XML.

Parecidos a los archivos *.dtd, pero permiten definir una serie de tipos como string, int, integer, etc. Y poseen un mecanismo para crear nuevos tipos, simples y complejos que representan los tipos de documentos XML.


Tanto Eclipse como NetBeans poseen herramientas para crear estos archivos XML.


Estructura básica de un XML Schema

<?xml version=”1.0” encoding=”UTF-8”?>
<xs:schema xmlns:xs=”http://www.w3.org./2009/XMLSchema”>
<!-- aquí pones los elementos y/o descripción del Schema -->
</xs:schema>



Definición de tipos simples

1.     Mediante enumeración
2.     Mediante derivación
3.     Mediante unión

<xs:simpleType name=”Algo”>
</xs:simpleType>



Definición de tipos complejos

<xs:complexType name=’Algo’>
<xs:sequence>
</xs:sequence>
</xs:complexType>

Ejemplo.  Crear una estructura “persona” con 4 atributos: nombre, edad, peso, y talla.

persona.xsd

<?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?>
<xs:schema xmlns:xs=”http://www.w3.org/2009/XMLSchema ”>
<xs:element name=”Persona” type=”tPersona”/>
<xs:complextType name=”tPersona”>
<xs:sequence>
<xs:element name=”nombre” type=”xs:string”/>
<xs:element name=”edad” type=”xs:integer”/>
<xs:element name=”peso” type=”xs:double”/>
<xs:element name=”talla” type=”xs:double”/>
</xs:sequence>
</xs:complexType>
</xs:schema>


persona.xml

<Persona xmlns:xs=”http://www.w3.org/2009/XMLSchema -instance” xsi:noNamespaceSchemaLocation=”persona.xsd”>
<nombre>Horacio</nombre>
<edad>20</edad>
<peso>56</peso>
<talla>1.65</talla>
</Persona>

Ejemplo con NetBeans

1. Bajar  e instalar el pugin  XMLTools

2. Crear el XML Schema

3.  Crear el JAXB Binding (elegir en verbose)

4. Crear el archivo xml

5. Crear la clase java que lea el xml


Ejemplo con Eclipse

1.     Crear el XML Schema
2.     Generar:  XML File  y/o JAXB Class
3.     Crear la clase java que lea el xml

Jai un lenguaje de programación inspirado en C++

Hoy hablaremos de un nuevo lenguaje de programación llamado Jai . Se trata de un lenguaje de programación que está desarrolland...

Etiquetas

Archivo del blog