 Tutoriales
Apuntes de XML
XML y las bases de datos
Generar XML a partir de consultas
- Para generar XML a partir de datos almacenados en una base de
datos, es necesario llevar a cabo dos tareas:
- Ejecutar hacia la base de datos la consulta deseada.
- Construir un documento XML a partir de los datos
obtenidos por la consulta. La forma más cómoda de hacer esto es
por medio de DOM.
- Veamos un ejemplo que ilustra esto:
import java.io.*;
import java.sql.*;
import org.w3c.dom.*;
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xml.serialize.*;
class BDToXML {
public static void main(String args[]) {
try{
Class.forName("com.inet.tds.TdsDriver");
String url = "jdbc:inetdae7:localhost?database=Northwind";
Connection con = DriverManager.getConnection(url,"sa","");
Statement st = con.createStatement();
String sql = "SELECT * FROM CUSTOMERS";
ResultSet res = st.executeQuery(sql);
Document doc = new DocumentImpl();
Element raiz = doc.createElement("Resultado");
ResultSetMetaData rMeta = res.getMetaData();
int nCols = rMeta.getColumnCount();
while (res.next()) {
Element reg = doc.createElement("Elemento");
reg.setAttribute(rMeta.getColumnName(1), res.getString(1));
for(int i=2; i<=nCols; i++) {
Element campo = doc.createElement(rMeta.getColumnName(i));
campo.appendChild(doc.createTextNode(res.getString(i)));
reg.appendChild(campo);
}
raiz.appendChild(reg);
}
doc.appendChild(raiz);
con.close();
OutputFormat formato = new OutputFormat(doc, "UTF-8", true);
StringWriter s = new StringWriter();
XMLSerializer ser = new XMLSerializer(s, formato);
ser.serialize(doc);
System.out.println(s.toString());
}
catch(ClassNotFoundException ex){
System.out.println(ex);
}
catch(SQLException ex){
System.out.println(ex);
}
catch(IOException ex){
System.out.println(ex);
}
}
}
- La primera parte del código ejecuta la consulta deseada
y obtiene los resultados en un objeto de la clase
ResultSet.
- Para ello es necesario previamente cargar un controlador y
especificar una URL acordes con la BD que se desee utilizar.
- Estas instrucciones y otras que siguen corresponden a la API
JDBC, cuyos detalles están más allá del alcance de este
curso.
- Después se trata de transferir los datos del objeto
ResultSet a un árbol DOM.
- En este ejemplo concreto cada registro de los
resultados se convierte en un elemento XML. El primer campo se
convierte en un atributo y el resto en subelementos.
- Una vez creado el árbol DOM, imprimimos el documento
XML por pantalla, aunque fácilmente se podría llevar a un fichero
o realizar alguna otra acción.
Transferir datos desde documentos XML
- El paso de datos en XML a una base de datos es un poco más
engorroso.
- Se trata de construir y ejecutar una serie de sentencias
SQL de inserción a partir de los datos contenidos en el
documento XML.
- Veamos los detalles de esta tarea con un ejemplo:
import java.io.*;
import java.sql.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
class XMLToBD {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Debe haber un parámetro (el fichero)");
}
else {
String fich = args[0];
System.out.println("Generando árbol para: " + fich + "\n");
try {
Class.forName("com.inet.tds.TdsDriver");
String url = "jdbc:inetdae7:localhost?database=Northwind";
Connection con = DriverManager.getConnection(url,"sa","");
Statement st = con.createStatement();
DocumentBuilder parser;
DocumentBuilderFactory factoria =
DocumentBuilderFactory.newInstance();
parser = factoria.newDocumentBuilder();
Document doc = parser.parse(fich);
Element raiz = doc.getDocumentElement();
String tabla = raiz.getNodeName();
String sqlFija = "INSERT INTO " + tabla + "(";
String nombre = tabla.substring(0, tabla.length() - 1);
NodeList elems = raiz.getElementsByTagName(nombre);
Node primero = elems.item(0);
NodeList campos = primero.getChildNodes();
for (int i=0; i<campos.getLength(); i++) {
Node n = campos.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE) {
sqlFija += ((i==1)? "" : ", ") + n.getNodeName();
}
}
sqlFija += ") VALUES ";
for (int i=0; i<elems.getLength(); i++) {
String sqlVar = "(";
Node n = elems.item(i);
NodeList hijos = n.getChildNodes();
for (int j=0; j<hijos.getLength(); j++) {
Node hijo = hijos.item(j);
if (hijo.getNodeType() == Node.ELEMENT_NODE) {
sqlVar += ((j==1)? "'" : ", '") +
hijo.getFirstChild().getNodeValue() + "'";
}
}
sqlVar += ")";
st.executeUpdate(sqlFija + sqlVar);
System.out.println(sqlFija);
System.out.println(sqlVar);
System.out.println();
}
}
catch (IOException e) {
System.out.println(e);
}
catch (SAXException e) {
System.out.println(e);
}
catch (ParserConfigurationException e) {
System.out.println(e);
}
catch(ClassNotFoundException ex){
System.out.println(ex);
}
catch(SQLException ex){
System.out.println(ex);
}
}
}
}
- En la primera parte se realiza la conexión con la BD y
se deja preparado un objeto Statement que nos servirá
para ejecutar las sentencias de inserción.
- Posteriormente obtenemos el árbol DOM para el documento
XML de origen.
- A partir del elemento raíz y el primer subelemento de éste,
construímos la primera parte del SQL necesario para
realizar inserciones de registros.
- Esta parte será fija para todas las inserciones, y contiene el
nombre de la tabla y los nombres de sus campos.
- Después, para cada elemento del documento XML que cuelgue del
elemento raíz completamos la sentencia de inserción con los
valores contenidos en el elemento y ejecutamos la
sentencia.
- En este ejemplo concreto se ha supuesto que el nombre del
elemento raíz coincide con la tabla destino y que los
elementos que cuelgan del raíz se nombran con el
singular del elemento raíz.
Herramientas
- Hemos visto ejemplos de la programación del proceso de
conversión XML BD en ambos sentidos, por medio de las APIs
DOM y JDBC.
- Existen APIs de más alto nivel que nos ayudan en la
programación de ese proceso.
- También existen multitud de productos que nos proporcionan
automáticamente esa conversión mediante un interfaz visual.
- Cada forma de realizar la conversión tiene su punto fuerte:
- La programación nos proporciona un completo
control sobre el proceso de transformación y es válida en
mayor número de circunstancias, a costa de un mayor trabajo.
- Las herramientas automáticas facilitan mucho el
trabajo, a costa de menos control en el proceso y menor
rango de situaciones de uso.
XML como almacén de datos
- Hemos visto ampliamente cómo XML es un formato totalmente
orientado hacia los datos.
- Vimos en la introducción que uno de los usos de XML es la
configuración. Hay ejemplos reales bastante importantes de
este uso, como los descriptores para EJBs, o la configuración del
servidor de servlets Apache Tomcat.
- Lo siguiente es preguntarnos si podríamos llegar a tener
como base de datos un sistema que funcione exclusivamente
con XML.
- Dicho sistema nos ahorraría las conversiones que hemos
analizado en los apartados anteriores, ganando principalmente en
rapidez.
- Hay una serie de problemas que van en contra, al menos
a corto plazo, de esta posibilidad:
- Multitud de aplicaciones (por no decir casi todas) que
utilizan actualmente algún sistema de bases de datos
relacionales (Oracle, SQL Server, Sybase, MySQL, etc.).
- Tamaño de las bases de datos necesarias.
- Representación en XML de datos relaciones.
- De todas formas, ya existen multitud de sistemas de
BBDD que funcionan exclusivamente con XML y que pueden ser válidos
en determinadas circunstancias (pequeñas cantidades de datos,
sistemas no heredados, etc.).
|
|
|