Anuncios

Bienvenidos sean a este post, hoy veremos como escribir archivos con formato XML.

Anuncios

En el post anterior vimos como leer el contenido de un archivo XML de una manera muy simple, en el caso de las escrituras de este tipo de archivo es un poco mas compleja dado que vamos a necesitar varios elementos que por el momento hablaremos superficialmente y mas adelante hablaremos de forma especifica, para ello vamos a crear un nuevo proyecto que llamaremos xml_writer, al igual que vimos en el post anterior debemos modificar Cargo.toml y agregar la siguiente linea en el sector de dependencies:

xml-rs = "0.8"
Anuncios

Con esta modificacion realizada pasemos a cambiar el codigo generado en main.rs con el siguiente:

main.rs

extern crate xml;

use std::fs::File;
use std::io::Write;
use xml::writer::*;

fn escribe_bloque_elem <W: Write, F: Fn(&mut EventWriter<W>)>
		(element: &str, w: &mut EventWriter<W>, f: F)
{
	let mut evento: XmlEvent =  XmlEvent::start_element(element).into();
	w.write(evento);
	f(w);
	evento = XmlEvent::end_element().into();
	w.write(evento);
}

fn maneja_evento<W: Write>(w: &mut EventWriter<W>)
{
	return escribe_bloque_elem("HTML", w, |w| {
		escribe_bloque_elem("HEAD", w, |w| {
		escribe_bloque_elem("TITLE", w, |w| {
			let evento: XmlEvent = 
				XmlEvent::Characters("Titulo").into();
			w.write(evento);
			});
		});

		escribe_bloque_elem("BODY", w, |w| {
		escribe_bloque_elem("DIV", w, |w| {
			let evento: XmlEvent = 
				XmlEvent::Characters("Contenido Div").into();
			w.write(evento);
			});
		});
	});
}

fn main() -> Result<()>
{
	let mut archivo = File::create("salida.xml").unwrap();
	let mut escritor = EmitterConfig::new().perform_indent(true).
				create_writer(&mut archivo);
	maneja_evento(&mut escritor);
	Ok(())
}
Anuncios

Este sera nuestro nuevo codigo, se ve complejo pero no lo es tanto para ello vamos a verlo en varios bloques, analicemos el primero:

extern crate xml;

use std::fs::File;
use std::io::Write;
use xml::writer::*;
Anuncios

Tal como vimos en el post anterior la primera linea se encarga de utilizar la dependencia que agregamos al principio, la cual sera la responsable de todo el tema del XML, las siguientes tres lineas se seran utilizadas respectivamente para:

  • Darnos todo lo necesario para manejar los archivos
  • Nos da la posibilidad de las acciones de escritura en los dispositivos
  • Sera la encargada de escribir los archivos XML
Anuncios

Despues tendremos la siguiente funcion:

fn escribe_bloque_elem <W: Write, F: Fn(&mut EventWriter<W>)>
		(element: &str, w: &mut EventWriter<W>, f: F)
{
	let mut evento: XmlEvent =  XmlEvent::start_element(element).into();
	w.write(evento);
	f(w);
	evento = XmlEvent::end_element().into();
	w.write(evento);
}
Anuncios
Anuncios

Esta sera la funcion encargada de escribir cada uno de los bloques de nuestro archivo, que manejara dos tipos de datos, uno de tipo Write proveniente de std::io (W) y otro de tipo Funcion el cual recibira un dato de tipo EventWriter siendo este el encargado de recibir la funcion que escribira en el archivo, despues tenemos los argumentos que recibira la funcion en si, observen que el primero sera el texto a escribir, luego el objeto que usaremos para escribir y por ultimo una funcion, lo sigueinte sera crear una variable llamada evento de tipo XmlEvent y de ella usaremos el metodo start_element para indicar que sera el primer tag y el nombre sera pasado por medio del valor que informamos en element e into es para escribirlo dentro, despues usamos write para escribir lo almacenado en evento, ejecutamos la funcion que informamos, volvemos a redefinir a evento y en este caso usamos a end_element para que cierre el tag que hicimos con start_element y por ultimo lo volvemos a escribir, pasemos al siguiente bloque:

fn maneja_evento<W: Write>(w: &mut EventWriter<W>)
{
	return escribe_bloque_elem("HTML", w, |w| {
		escribe_bloque_elem("HEAD", w, |w| {
		escribe_bloque_elem("TITLE", w, |w| {
			let evento: XmlEvent = 
				XmlEvent::Characters("Titulo").into();
			w.write(evento);
			});
		});

		escribe_bloque_elem("BODY", w, |w| {
		escribe_bloque_elem("DIV", w, |w| {
			let evento: XmlEvent = 
				XmlEvent::Characters("Contenido Div").into();
			w.write(evento);
			});
		});
	});
}
Anuncios

Esta sera la funcion que se encargara de manejar los eventos, es decir que sera la que llamara a la funcion que definimos anteriormente para poder escribir los elementos, en este caso solo manejara un tipo como es Write pero recibira el tipo EventWriter, dentro usaremos un return para devolver una serie de llamadas a la funcion escribe_bloque_elem.

Anuncios
Anuncios

La primera sera para escribir el bloque HTML, observen que pasamos el dato que identificara al bloque, luego le pasamos, el argumento informado en la funcion (w) y por ultimo usamos dos operadores que se encarga de pasar el argumento entre ellos a la funcion que informemos, en este caso volvemos a usar la misma funcion pero pasaremos otro identificador para el siguiente bloque, volvemos a hacer lo mismo pero esta vez crearemos una variable llamada evento para escribir dentro de este bloque y por ultimo usamos write para escribirlo, despues simplemente cerramos las dos ultimas llamadas de funciones.

Anuncios

Volvemos a repetir lo mismo pero esta vez usaremos el tag BODY y el tag DIV para escribir un texto, vean que el bloque es exactamente igual a lo que hicimos anteriormente pero esta vez si cerraremos a los dos nuevos llamados y al llamado principal, con esto ya tenemos la funcion que se encargara de crear los distintos bloques de la pagina por medio de la funcion anterior, pasemos a ver el ultimo bloque:

fn main() -> Result<()>
{
	let mut archivo = File::create("salida.xml").unwrap();
	let mut escritor = EmitterConfig::new().perform_indent(true).
				create_writer(&mut archivo);
	maneja_evento(&mut escritor);
	Ok(())
}
Anuncios
Anuncios

Esta es la funcion main, volvemos a utilizar Result para capturar cualquier tipo de error, lo primero que haremos sera usar a create de File para crear el archivo, del cual hablamos en este post, en este caso usamos a unwrap para que ante cualquier error nos lo notifique, lo siguiente sera el encargado de manipular al archivo, donde por medio de EmitterConfig crearemos el objeto que se encargara de enviar todos los datos con el formato XML o tags, para ello usamos un parametro para que permite sangria dentro del mismo (perform_indent) y luego usamos a create_writer para informarle el archivo de destino y con este comenzar a escribirlo, por ultimo usamos la ultima funcion que creamos y le pasamos el manejador de archivo XML, como ultimo paso de nuestro bloque volvemos a usar el Ok para que Result entienda que esta todo bien, compilemos y veamos el resultado.

Anuncios
Nota:
Puede devolver algunos avisos en la compilacion pero no se preocupen porque deberia funcionar, son solo notificaciones de metodos no usados.
Anuncios

Si lo ejecutan les creara un archivo nuevo llamado salida.xml y si lo visualizamos debera tener un codigo como el siguiente:

salida.xml

<?xml version="1.0" encoding="utf-8"?>
<HTML>
  <HEAD>
    <TITLE>Titulo</TITLE>
  </HEAD>
  <BODY>
    <DIV>Contenido Div</DIV>
  </BODY>
</HTML>
Anuncios

En resumen, hoy hemos visto como escribir un archivo XML, hemos visto lo basico que se necesita para poder implementarlo, despues hemos visto dos funciones necesarias para poder trabajar, tambien hemos los modulos basicos que necesitaremos, por ultimo hemos visto como se utiliza, como se llama un metodo al otro, como llamarlo desde la funcion principal y por ultimo como quedo nuestro archivo creado, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50