martes, 4 de noviembre de 2008

Codificación: datos de la aplicación como recursos XML embebidos (parte II).

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

II. La definción del archivo XML.

Para empezar con algo realmente simple, supongamos la siguiente estructura de menú definida en XML:

<?xml version="1.0" encoding="utf-8" ?>
<menu id="inicio">
  <titulo>Mi ERP 0.0.1</titulo>
  <submenues>
    <menu id="compras">
      <titulo>Compras</titulo>
      <submenues>
        <menu id="compras_presupuestos">
          <titulo>Presupuestos</titulo>
        </menu>
        <menu id="compras_ordenes">
          <titulo>Ordenes</titulo>
        </menu>
        <menu id="compras_seguimiento">
          <titulo>Seguimiento</titulo>
        </menu>
      </submenues>
    </menu>
    <menu id="ventas">
      <titulo>Ventas</titulo>
      <submenues>
        <menu id="ventas_catalogo">
          <titulo>Catálogo</titulo>
        </menu>
        <menu id="ventas_pedidos">
          <titulo>Pedidos</titulo>
        </menu>        
      </submenues>
    </menu>    
  </submenues>
</menu>

Como verán, es una organización recursiva de elementos menu. Cada uno de ellos tiene un atributo id que lo identifica unívocamente, un elemento título que corresponde al texto a mostrar al usuario y un elemento submenues que contiene una lista de elementos menu, cada uno de ellos con las mismas características.

En el ejemplo estamos definiendo la siguiente estructura de menú:

Mi ERP 0.0.1
 Compras
  Presupuestos
  Ordenes
  Seguimiento
 Ventas
  Catálogo
  Pedidos

Es lo mínimo indispensable para sacar algo por pantalla. Así que lo primero que tenemos que hacer es agregar un nuevo archivo xml al proyecto y establecerlo como recurso embebido. Esto último le indica al compilador que debe incrustar el archivo xml en el ensamblado.

Ya estamos listos para escribir la definción (o mejor, copiar y pegar el ejemplo anterior) y hacer una pequeña prueba: colocamos un botón sobre el formulario del proyecto. El código para el botón será:

        private void button1_Click(object sender, EventArgs e)
        {
            string resourceName = "EjemploRecursosXMLEmbebido.Menu.xml";
            
            XmlDocument menuesXML = new XmlDocument();
            using (Stream s = this.GetType().Assembly.GetManifestResourceStream(resourceName))
            {
                menuesXML.Load(s);
            }

            XmlNodeList titulos = menuesXML.SelectNodes("descendant::titulo");
            foreach (XmlNode titulo in titulos)
                MessageBox.Show(titulo.InnerText);

        }

(Nota: hay que agregar los using a los namespaces System.IO y System.Xml para que compile.)

La idea es cargar el archivo en un objeto XmlDocument para poder acceder a los datos por código utilizando XPath, que es el lenguaje de consulta para XML. Como prueba presentamos un MessageBox para cada título de menú en el archivo.

Aquí ya tenemos un par de líneas para resaltar. Por un lado, noten el nombre que se le asigna al recurso embebido: [nombre del ensamblado].[nombre del archivo (con extensión)]. En nuestro caso: "EjemploRecursosXMLEmbebido.Menu.xml".

El archivo se encuentra incrustado como recurso en el ensamblado. Para recuperarlo tenemos que obtener una referencia al ensamblado que lo contiene (clase Assembly) y a través del método GetManifestResourceStream obtener un Stream. Todo es lo hace la instrucción

using (Stream s = this.GetType().Assembly.GetManifestResourceStream(resourceName))

que coloca la referencia al Stream en la variable s.

Luego pasamos esa referencia como parámetro al método Load de un objeto XmlDocument. En nuestro caso, la variable menuesXML contiene al documento, por lo que hacemos:

menuesXML.Load(s);

El resto del código obtiene todos los nodos "titulo" del documento y muestra el texto que contiene.

La magia se termina aquí (no era mucha). Investigando un poco de XPath ya se podría recorrer el documento e ir cargando los datos en, por ejemplo, un TreeView. Lo que haremos de aquí en más será brindarle estructura a la solución de manera de hacerla funcional (todo muy lindo, pero esto no hace nada) y más sólida, mantenible y reutilizable.

Parte I: Resumen.

Parte II: La definción del archivo XML.

Parte III: Encapsulamiento.

Parte IV: Que funcione.

No hay comentarios.: