E4X, Javascript y XML

noviembre 13, 2010

Hace un tiempo, acceder a documentos XML era perfectamnete posible, pero había que pasar por APIs que quizás no eran todo lo sencillas que deberían ser.

Las dos principales APIs que nos servían para procesar un documento XML eran DOM y SAX. Los nombres describían la forma de acceder al documento, mientras que en DOM se cargaba todo el documento en memoria, y podiamos acceder de una forma más sencilla, en SAX registrabamos una serie de “callbacks” a los que se nos iba llamando segun se procesaba el documento.

Sin duda DOM era mas sencilla desde el punto de vista del uso, pero menos eficiente, si nuestro documento era muy grande, necesitabamos tenerlo completamente en memoria. Por su lado SAX era más eficiente, pero la forma de desarrollar con él era bastante incomoda, ya que teniamos que separar nuestro código en multiples funciones de callback y nosotros teniamos que ser responsables de mantener el estado entre las diferentes llamadas.

Sin duda, hoy en día XML es el lenguaje de intercambio de datos más extendido (ya veremos en unos pocos años si esto sigue siendo así). Y sobre todo teniendo en cuenta que en el entorno del navegador, usar XML suele (o solía) ser común para intercambiar datos usando AJAX.

Debido a todo esto, poco a poco los lenguajes han ido incorporando mecanismos cada vez más comodos para procesar los documentos XML, como por ejemplo en Java JAXP . En este caso vamos a hablar sobre E4X, o la extensión de ECMAScript para el procesado de documentos XML.

Tratar un documento XML con esta extensión es sumamente sencillo, de hecho, el propio código habla por si mismo.

var library = <library postalcode="28000">
<books>
<book id="1">
  <title>Book Title 1</title>
  <author>Author of Book 1</author>
</book>
<book id="2">
  <title>Book Title 2</title>
  <author>Other Author of Book 2</author>
</book>
</books>
<magazines>
<magazine id="1">
<title>Magazine title 1</title>
</magazine>
</magazines>
</library>

alert(library.books.book[0].title); // Book Title 1
alert(library.books.book.(@id == "2").author); // Other Author of Book 2

Como veis, el procesado de un documento XML se simplifica de una manera dramática. Al mapear un documento XML a un objeto, su forma de acceso es practicamente similar a como lo haríamos con dicha estructura de datos.

La sintaxis de acceso al documento nos recuerda en cierta manera a XPath, pudiendo hacer cosas como:

alert(library.books..*.length()) 
	// El operador .. accede a todos los hijos.
alert(library.magazines.magazine[0].@id) 
	// Usando el operador @ accedemos a los atributos
alert(library.books.book.(@id == "2").author); 
	// Podemos filtrar por el valor de los atributos

Además de ayudar a procesar un documento, tambien tenemos facilidad para generar XML, si “encerramos” una expresion entre {}, se sustituirá por su valor, o incluso usando el operador +, añadiremos nuevos elementos al documento.

var b = "book"
var xmlDoc = <{b}><title>The Title</title></{b}>
alert(xmlDoc.toXMLString())

library.books.book += <book id="3"><title>....</book>

Después de ver todo lo que E4X puede hacer por nosotros, ahora contaremos la parte mala :).

Actúalmente, solo esta soportado en productos de Mozilla, esto es, Firefox, Thunderbird o Rhino, además de ActionScript, pero no se puede utilizar en Chrome, Safari o Internet Explorer. Y, ¿Por qué sucede esto?, pues básicamente por que los desarrolladores de los navegadores no consideran que sea necesaria esta implementación, ya que consideran que el acceso estandar usando DOM en Javascript es lo suficientemente versatil como para no necesitar nada más. Además, librerías como JQuery tienen extensiones para manejar documentos XML.

En cualquier caso, al ser un estandar nos garantizamos que si algun día deciden incorporar E4X en los navegadores actúalmente no soportados, funcionará de forma identica a la que lo hace ahora mismo en Firefox o incluso en ActionScript.

Anuncios

Aplicación de escritorio usando Javascript

noviembre 1, 2010

El otro día me preguntaba si seria posible hacer una aplicación de escritorio usando Javascript. Como sabemos, Javascript es uno de los lenguajes que mas peso ha tenido en los últimos años, y que ha tenido que sufrir la guerra de navegadores e implementaciones a la que hemos sido testigos recientemente.

Sin embargo, Javascript es un lenguaje fascinante, con aspectos muy avanzados y que poco a poco ha ido añadiendo cosas cada vez mas interesantes, como por ejemplo sus interesantes mecanismos de introspección y ejecución de código de forma dinámica.

Pero, en esta entrada nos vamos a centrar en como hacer una aplicación de escritorio usando Javascript, cosa que seguramente no sea muy habitual.

Para ello, nos vamos a valer de la plataforma con la que mas se confunde Javascript y que nada tiene que ver, si, estamos hablando de Java. Aun recuerdo las noches que pasaba por el IRC, mas concretamente en el canal #java, la cantidad de gente que entraba a preguntar cosas sobre javascript era tremenda. Lo cierto es que el nombre no ayuda, y la confusión es bastante probable.

Aunque hay varias opciones, he elegido Java como opción ya que aporta varias cosas importantes, por un lado es su gran librería gráfica Swing, que esta integrada en la plataforma, por otro lado su característica mas destacable, la multiplaformidad, lo mismo se ejecuta en Linux, OSX o Windows. Estas dos cosas son ventajas en su mismas de Java, lo que actúa como nexo de unión es Rhino (http://www.mozilla.org/rhino/).

Rhino es una librería hecha por mozilla, que permite integrar Javascript totalmente en la plataforma de Java. Lo cierto es que Rhino esta integrado desde la versión 1.6 dentro de Java, por lo que si queremos interpretar código javascript en Java, no necesitamos nada mas que la propia JDK, sin embargo, en el paquete de rhino, aparte de la librería, viene un interprete interactivo de javascript que es bastante útil.

Lo cierto es que gracias a la integración entre Java y Javascript, hacer una aplicación de escritorio es bastante sencillo. Si por ejemplo ejecutamos el siguiente programa:

var frame = new javax.swing.JFrame();
frame.setSize(200,200);
frame.setVisible(true);
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

Usando el interprete de rhino:

java -jar js.jar prueba.js

Obtendremos, como esperamos, una ventana vacía.

Como vemos, este método es sencillo y bastante potente para realizar prototipos, ya que podemos probar cualquier código java, usando las comodidades de Javascript y quitandonos el paso de la compilación.

Incluso, podremos usar la consola interactiva de Javascript, para ir modificando la interfaz poco a poco, e ir viendo los cambios sobre la marcha.

Sin duda, uno de los beneficios de Javascript que aprovechamos en esta forma de interactuar con swing son la posibilidad de definir una función en la llamada que añade los listeners a los controles. Así por ejemplo, si tenemos un botón, podemos definir el código controlador que se lanza al pulsarlo, en la propia llamada al método addActionListener.

Como en el siguiente código:

function main() {
	var frame = new javax.swing.JFrame();
	frame.setSize(200,200);
	frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
	
	var button = new javax.swing.JButton("Push Me!");
	var label = new javax.swing.JLabel("JLabel");
	var panel = new javax.swing.JPanel();
	
	button.addActionListener(function() {
		label.setText("Pressed!")
	});
	
	panel.add(button);
	panel.add(label);
	
	frame.getContentPane().add(panel);
	
	frame.setVisible(true);
}

Después de ver todo esto, queda respondida la duda que iniciaba el post. Si, se pueden hacer aplicaciones de escritorio usando Javascript, claro que con la inestimable ayuda de Java y Rhino 🙂