Mejor guardado para XML

(1/1)

Meta:
Tengo este código para guardar y recuperar datos en XML.

Siempre me dicen que use getters y setters.

La forma que me enseñaron es antigua y nada que ver con ahora.

Por ejemplo.
Código
using System.Xml;
 
namespace Guardar_y_cargar_datos_en_archivo.xml_.NET_7._0
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();
       }
 
       // Guarda los datos introducidos a parte de crear el archivo "miXML.xml".
       private void button_Guardar_Click(object sender, EventArgs e)
       {
           XmlWriter w = XmlWriter.Create(@"archivo.xml");
           w.WriteStartElement("MiInfo");
           w.WriteElementString("TextBox", textBox1.Text);
           w.WriteElementString("CheckBox", checkBox1.Checked.ToString());
           w.WriteElementString("radioButton1_Luz_ON", radioButton1.Checked.ToString());
           w.WriteElementString("radioButton2_Luz_OFF", radioButton2.Checked.ToString());
           w.WriteEndElement();
           w.Close();
       }
 
       private void Form1_Load(object sender, EventArgs e)
       {
           try
           {
               XmlReader r = XmlReader.Create("archivo.xml");
               r.ReadStartElement("MiInfo");
               textBox1.Text = r.ReadElementContentAsString();
               checkBox1.Checked = Convert.ToBoolean(r.ReadElementContentAsString());
               radioButton1.Checked = Convert.ToBoolean(r.ReadElementContentAsString());
               radioButton2.Checked = Convert.ToBoolean(r.ReadElementContentAsString());
               r.ReadEndElement();
               r.Close();
           }
           catch (Exception)
           {
 
               //
           }
       }
   }
}

Por supuesto, me funciona como me han enseñado.
El archivo es este que se queda guardado.

Código
<?xml version="1.0" encoding="utf-8"?>
<MiInfo>
<TextBox>Hola amigo.</TextBox>
<CheckBox>True</CheckBox>
<radioButton1_Luz_ON>False</radioButton1_Luz_ON>
<radioButton2_Luz_OFF>True</radioButton2_Luz_OFF>
</MiInfo>

Entonces.

¿Cuál es la mejor manera de programarlo?

Saludos.

**Aincrad**:
Por que no usar json ? si quieres modernizarte, puedes usar : SettingsProvider.net es el que uso en todas mis apps , es realmente bueno.

Si todavía quieres usar XML, puedes buscar algún snippet aquí :  https://foro.elhacker.net/net/indice_de_la_libreria_de_snippets_para_vbnet-t485444.0.html y puedes convertir de VB a C# usando : https://converter.telerik.com

Eleкtro:
La consulta que realizas se puede interpretar de varias formas. ¿Cual es exactamente el aspecto que buscas mejorar de ese código?. Utilizar directamente el método getter/setter de una o varias propiedades para controlar de forma eventual el cómo y el cuando guardar cierta configuración del usuario, eso podría no suponer mejor estructuración del código, ni tampoco mejora alguna con respecto a la utilización de la clase XmlWriter para llevar a cabo esa tarea.

En cualquier caso, no lo harías utilizando directamente la clase XmlReader para escribir elementos, sino utilizando los métodos de serialización destinados a convertir objetos en sus respectivos valores serializables, mediante la clase XmlSerializer:

learn.microsoft.com - Clase XmlSerializerlearn.microsoft.com - Uso de Visual C# para serializar un objeto en XMLlearn.microsoft.com - Ejemplos de serialización XML

En ciertos casos podrías recurrir a utilizar los correspondientes atributos de clase relacionados son la serialización de un tipo (clase o estructura, y sus miembros definidos) en formato Xml, e implementar la interfaz IXmlSerializable en dicho tipo, junto al uso de la clase XmlWriter (aquí, sí) para controlar y personalizar la serialización en formato Xml de sus miembros definidos.

Relacionado con esto, comparto aquí un ejemplo propio, de una clase por nombre "ColorString" que representa el valor de un color ARGB expresado en diferentes representaciones textuales. La clase implementa las interfaces ISerializable e IXmlSerializable:

https://pastebin.com/8C19nZFv

Nota: El código original está escrito en VB.NET; esto es una conversión automática del código a C#, probablemente haya errores de sintaxis en la consersión, y en cualquier caso NO es un código funcional (faltan referencias a otros miembros que no he añadido), es solo un ejemplo. Puedes encontrar otros ejemplos más reducidos y funcionales empezando por este:

learn.microsoft.com - Interfaz IXmlSerializable

O quizás al mencionar los métodos getters/setters más bien te estés refiriendo a la estructura 'Settings' que se encarga de crear código autogenerado con las propiedades que especifiques (en la pestaña "Settings" de las propiedades de tu proyecto .NET 7.0) a través del archivo "app.config" para administrar la configuración de la aplicación.

Lo cierto es que, a menos que tengas alguna razón justificable por la cual prefieras guardar la configuración en formato Xml (o en json, o en binario, me es indiferente) 'Settings' es lo que deberías usar para guardar la configuración del usuario:

learn.microsoft.com - Introducción a la configuración de la aplicaciónlearn.microsoft.com - Administración de la configuración de la aplicación (.NET)learn.microsoft.com - Utilizar valores de configuración de aplicación y de usuario
PD: Esta característica está disponible desde que surgió .NET 2.0; En caso de que esto sea a lo que te estuvieses refiriendo, decir que hasta ahora estabas usando "la forma antigua" con Xml no sería muy excusable por parte de quien te haya enseñado esa forma :xD, pero tampoco por parte tuya.


Cita de: **Aincrad** en  9 Marzo 2024, 23:24 pm

Por que no usar json ? si quieres modernizarte, puedes usar : SettingsProvider.net es el que uso en todas mis apps , es realmente bueno.


No lo conocía. ¡Lo probaré a ver que tal!.

Ya que estamos hablando de formas para administrar la configuración del usuario, me gustaría aportar otra alternativa diferente de utilizar JSON para llevar a cabo esa función:

Jot - a .NET library for state persistence
Cita del autor:
"Con Jot, solo necesita declarar qué propiedades de qué objetos desea rastrear y cuándo conservar y aplicar los datos."

Esto implica que no tenemos que escribir ningún código adicional para obtener ni asignar directamente los valores de la configuración. Eso se realiza de forma abstracta, sofistacadamente.

Es muy versatil y, además, ofrece simplicidad de uso mediante el patrón de diseño de interfaz fluida (Fluent interface) que nos permite encadenar varias sentencias en pocas líneas para controlar y condicionar, con belleza y precisión, el funcionamiento y el comportamiento de carga y guardado de los valores de la configuración, pudiendo asignar nombres de eventos en los que se ha de guardar un valor de la configuración, o condiciones especiales para no hacerlo, entre otras cosas, y aislando prácticamente toda esta lógica del código fuente de la interfaz de usuario.

Meta:
Muchas gracias a los dos, muy buena info.  ;-)

Ya que estamos, lo he hecho con archivos de txt en el cual a nadie le interesa pero funciona.

Código
namespace Guardar_y_cargar_datos_en_archivo.txt_.NET_7._0
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();
       }
 
       private void Form1_Load(object sender, EventArgs e)
       {
           CargarControles();
       }
 
       void GuardarCrontoles()
       {
           string archivoDeTexto = "";
           int numero = 0;
 
           foreach (Control control in this.Controls)
           {
               if (control is Button)
                   continue;
               else if (control is TextBox)
                   archivoDeTexto += (numero++).ToString() + ": " + ((TextBox)control).Text + "\n";
               else if (control is CheckBox)
                   archivoDeTexto += (numero++).ToString() + ": " + ((CheckBox)control).Checked + "\n";
               else if (control is RadioButton)
                   archivoDeTexto += (numero++).ToString() + ": " + ((RadioButton)control).Checked + "\n";
               else if (control is GroupBox)
                   foreach (Control ctrl in ((GroupBox)control).Controls)
                       if (ctrl is TextBox)
                           archivoDeTexto += (numero++).ToString() + ": " + ((TextBox)ctrl).Text + "\n";
                       else if (ctrl is CheckBox)
                           archivoDeTexto += (numero++).ToString() + ": " + ((CheckBox)ctrl).Text + "\n";
                       else if (ctrl is RadioButton)
                           archivoDeTexto += (numero++).ToString() + ": " + ((RadioButton)ctrl).Text + "\n";
           }
 
           // Guardar archivo de texto en Controles.txt.
           File.WriteAllText("Controles.txt", archivoDeTexto);
       }
 
       void CargarControles()
       {
           int numero = 0;
           string[] lineas;
 
           if (File.Exists("Controles.txt"))
               lineas = File.ReadAllLines("Controles.txt");
           else
               return;
 
           foreach (Control control in this.Controls)
           {
               if (control is Button)
                   continue;
               else if (control is TextBox)
                   ((TextBox)control).Text = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0));
               else if (control is CheckBox)
                   ((CheckBox)control).Checked = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0)) == "True" ? true : false;
               else if (control is RadioButton)
                   ((RadioButton)control).Checked = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0)) == "True" ? true : false;
               else if (control is GroupBox)
                   foreach (Control ctrl in ((GroupBox)control).Controls)
                       if (ctrl is TextBox)
                           ((TextBox)ctrl).Text = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0));
                       else if (ctrl is CheckBox)
                           ((CheckBox)ctrl).Checked = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0)) == "True" ? true : false;
                       else if (ctrl is RadioButton)
                           ((RadioButton)ctrl).Checked = lineas[numero++].Substring(3 + (numero >= 10 ? 1 : 0)) == "True" ? true : false;
           }
       }
 
       private void button_Guardar_Click(object sender, EventArgs e)
       {
           GuardarCrontoles();
       }
   }
}

Y como dice arriba el compañero. ¿Por qué no json?

Pues también funciona.

Código
using System.Text.Json;
 
namespace Guardar_y_cargar_datos_en_archivo.json_.NET_7._0___02
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();
       }
 
       class MiInfo
       {
           public string? TextBox { get; set; }
           public bool CheckBox { get; set; }
           public bool RadioButton1_Luz { get; set; }
           public bool RadioButton2_Luz { get; set; }
       }
 
       // Guardar datos en el archivo Ejemplo.json.
       void GuardarDatos()
       {
           MiInfo miInfo = new()
           {
               TextBox = textBox1.Text,
               CheckBox = checkBox1.Checked,
               RadioButton1_Luz = radioButton1.Checked,
               RadioButton2_Luz = radioButton2.Checked
           };
 
               // Guardar con espacios en blanco el archivo .json.
               var opciones = new JsonSerializerOptions { WriteIndented = true };
               string serializado = JsonSerializer.Serialize(miInfo, opciones);
 
               // Crear archivo Ejemplo.json.
               File.WriteAllText(@"Ejemplo.json", serializado);
       }
 
       // Cargar datos en el archivo Ejemplo.json.
       void CargarDatos()
       {
           // ¿Existe el archivo Ejemplo.json?
           // if (File.Exists(@"Ejemplo.json") == true)
           if (File.Exists(@"Ejemplo.json"))
           {
               // Sí. Lee el archivo completo.
               string serializado = File.ReadAllText(@"Ejemplo.json");
               MiInfo? miInfo = JsonSerializer.Deserialize<MiInfo>(serializado);
 
               // ¿Es distinto a nulo?
               if (miInfo != null)
               {
                   // Sí. Lee los datos del archivo Ejemplo.json y los carga
                   // en sus componentes indicados.
                   textBox1.Text = miInfo.TextBox;
                   checkBox1.Checked = miInfo.CheckBox;
                   radioButton1.Checked = miInfo.RadioButton1_Luz;
                   radioButton2.Checked = miInfo.RadioButton2_Luz;
               }
           }
       }
 
       private void button_Guardar_Click(object sender, EventArgs e)
       {
           GuardarDatos();
       }
 
       private void Form1_Load(object sender, EventArgs e)
       {
           CargarDatos();
       }
   }
}

Contenido del json.
Código
{
 "TextBox": "Hola amigo.",
 "CheckBox": false,
 "RadioButton1_Luz": false,
 "RadioButton2_Luz": true
}

Salu2.  :D

Navegación

[0] Índice de Mensajes