XSLT para completar una tabla SQL con datos XML

En esta ocasión publicaré un post bastante básico sobre XML y XSLT, tecnologías que hacía más de una década no me tocaba combinar. Aquí queda por si en un futuro tengo que refrescar de nuevo la mente.

Hubo un tiempo en el que estuvo de moda XML y se aplicaba a todo lo conocido, incluso se hacían portales web que separaban la información de la representación usando XML y XSLT (antes de que se dotara de CSS al HTML).

Desde el punto de vista de notación de documentos es insuperable ya que permite expresar las relaciones entre los datos creando una sintaxis propia. Si tuviste la oportunidad de trabajar con XML al final te darías cuenta por qué otras formas de expresar documentos se han ido imponiendo:

  • Se trata de un lenguaje con una sintaxis estricta. Un carácter mal y adiós. Además suele ser complicado interpretar las indicaciones de las herramientas.
  • Es totalmente dependiente de su creador. Al poder definir las etiquetas, atributos y estructura, cada documento puede estar hecho de una forma determinada. Es cierto que existen XSD y DTD que los describen, pero al final es un lío.
  • Su sintaxis hacía que al final ocupasen más las etiquetas y atributos que la pripia información transportada.
  • Es complicado de procesar de forma automática con lenguajes de programación. Su estructura jerárquica variable puede ser una pesadilla.

Sea como fuere, hay ocasiones en la que no tenemos más remedio que hacer algún tipo de procesamiento de datos XML. En este post voy a exponer un caso real en el que tenemos una información que queremos introducir en una tabla de SQL. Para ello crearemos una hoja de transformación XSLT que transformará la información jerarquizada en formato XML a sentencias INSERT de SQL que podremos ejecutar para introducir los datos.

Los datos corresponden a un fichero XML de una especificación de aplicación gubernamental, y representan los posibles valores para un combo “sexo” en los diferentes idiomas admitidos. Además, cada valor (hombre o mujer) tiene un código asociado y un orden.

<?xml version="1.0" encoding="UTF-8"?>
<Table name="Tabla">
    <Item>
      <Code>000</Code>
      <Order>1</Order>
      <Name>
        <NameDetail lang="cat">
          <Name>Home </Name>
          <ShortName>Home</ShortName>
        </NameDetail>
        <NameDetail lang="spa">
          <Name>Hombre</Name>
          <ShortName>Hombre </ShortName>
        </NameDetail>
        <NameDetail lang="eus">
          <Name>Gizonezkoa </Name>
          <ShortName>Gizonezkoa</ShortName>
        </NameDetail>
        <NameDetail lang="glg">
          <Name>Home </Name>
          <ShortName>Home</ShortName>
        </NameDetail>
        <NameDetail lang="eng">
          <Name>Man  </Name>
          <ShortName>Man</ShortName>
        </NameDetail>
        <NameDetail lang="fra">
          <Name>Homme </Name>
          <ShortName>Homme </ShortName>
        </NameDetail>
      </Name>
      <Link>false</Link>
    </Item>
    <Item>
      <Code>010</Code>
      <Order>2</Order>
      <Name>
        <NameDetail lang="cat">
          <Name>Dona</Name>
          <ShortName>Dona</ShortName>
        </NameDetail>
        <NameDetail lang="spa">
          <Name>Mujer</Name>
          <ShortName>Mujer</ShortName>
        </NameDetail>
        <NameDetail lang="eus">
          <Name>Emakumezkoa</Name>
          <ShortName>Emakumezkoa</ShortName>
        </NameDetail>
        <NameDetail lang="glg">
          <Name>Muller</Name>
          <ShortName>Muller</ShortName>
        </NameDetail>
        <NameDetail lang="eng">
          <Name>Woman </Name>
          <ShortName>Woman</ShortName>
        </NameDetail>
        <NameDetail lang="fra">
          <Name>Femme</Name>
          <ShortName>Femme</ShortName>
        </NameDetail>
      </Name>
      <Link>false</Link>
    </Item>
  </Table>

Utilizando una hoja de estilos para la transformación del lenguaje, podremos curzarla con el fichero .xml para generar el texto que deseemos. Esta hoja de estilos está en formato XLST (http://en.wikipedia.org/wiki/XSLT) y existen diferentes servicios online que nos van a permitir introducir el XML, la hoja XSLT y obtener el procesamiento (cruce) de ambas. Por ejemplo podemos usar el siguiente: http://xslttest.appspot.com/

En el caso que nos ocupa, la hoja de estilos para la transformación es bastante sencilla porque la complejidad del fichero XML de datos tampoco es nada grande:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
	<xsl:template match="Table">
      <xsl:for-each select="Item">
			INSERT INTO TABLA_DESTINO (id, s_id_delegado, s_texto_spa, s_texto_glg, s_texto_eng, s_texto_cat, s_texto_eus, s_texto_fra) values ('<xsl:value-of select="Code"/>',null,'<xsl:value-of select="Name/NameDetail[@lang='spa']/Name" />','<xsl:value-of select="Name/NameDetail[@lang='glg']/Name" />','<xsl:value-of select="Name/NameDetail[@lang='eng']/Name" />','<xsl:value-of select="Name/NameDetail[@lang='cat']/Name" />','<xsl:value-of select="Name/NameDetail[@lang='eus']/Name" />','<xsl:value-of select="Name/NameDetail[@lang='fra']/Name" />');      
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>

Los puntos claves son:

  • La cabecera que define que es una hoja de estilos de transformación para XML.
  • El primer match para el tag “Table”. Este tag es el que se ha creado.
  • Un bucle que itera a través de todos los elementos que son hijos de “Table” y que son del tipo “Item”.
  • El texto que se va a imprimir por cada uno de los elementos que se cruzan del bucle anterior. Esta sentencia se compone de un texto parcial del INSERT DE SQL que queremos obtener como resultado.
  • Dentro del texto que se va a imprimir tenemos la obtención de los valores con el tag “xsl:value-of”. En este tag tenemos el atributo, que permite navegar por los elementos calificados como /Name/NameDetail[@lang=’eus’]/Name. Como puedes suponer con NameDetail[@lang=’eus’] nos permite seleccionar el tag NameDetail que tenga el atributo lang con el valor ‘eus’, que en este caso será en Euskera. Por tanto, /Name/NameDetail[@lang=’eus’]/Name, indica que se introduzca en el tag Name que tiene en su interior un tag NameDetail con atributo lang=’eus’ y luego vuelve a meterse otra vez en el tag Name para obtener el valor con “xsl:value-of”.
  • Finalmente los tags de cierre del bucle y del template.

Si empleamos un transformador online como por ejemplo http://xslttest.appspot.com/ y pegamos el XML y el XSLT en sus textarea correspondientes, obtendremos el siguiente resultado:

INSERT INTO TABLA_DESTINO (id, s_id_delegado, s_texto_spa, s_texto_glg, s_texto_eng, s_texto_cat, s_texto_eus, s_texto_fra) values ('000',null,'Hombre','Home ','Man ','Home ','Gizonezkoa ','Homme ');
INSERT INTO TABLA_DESTINO (id, s_id_delegado, s_texto_spa, s_texto_glg, s_texto_eng, s_texto_cat, s_texto_eus, s_texto_fra) values ('010',null,'Mujer','Muller','Woman ','Dona','Emakumezkoa','Femme');

Ahora simplemente tendremos que pegar estas sentencias XML en nuestro sistema gestor de base de datos y ejecutarlas.

Si dispones de un ordenador con sistema operativo basado en Unix, como por ejemplo Mac OSX, puedes usar un comando muy sencillo como es xsltproc para hacer la transformación, y además meterla en un .sh para poder automatizarla. En el siguiente script se hace para un fichero, incluyendo el commit al final (por si nuestra base de datos no tiene el AUTOCOMMIT activado). La tercera línea une todos los posibles ficheros acabados en RESULTADO.sql quitando los posible tags de cabecera XML y los almacena en TODOS_RESULTADOS.sql

xsltproc PLANTILLA.xsl DATOS.xml > 1_RESULTADO.sql
echo commit; >> 1_RESULTADO.sql

cat *RESULADO.sql |grep xml -v > TODOS_RESULTADOS.sql

En resumen, en este post hemos visto una técnica básica de transformación de datos XML en otro tipo de caracteres que nos puede ser de gran utilidad para transformar los datos en sentencias SQL para completar la información de nuestras tablas.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s