Programación de XML en múltiples niveles: Uso de XML en el nivel medio para obtener rendimiento, fidelidad y facilidad de desarrollo

Desarrollo de una solución de XML completa con JDBC 4.0, SQLXML, y el WebSphere Server XML Feature Pack

En este artículo, explore un enfoque natural y de alto desempeño hacia el trabajo con datos XML en la base de datos y el nivel medio. El enfoque se explica a través de una aplicación Web de muestra que combina datos XML en una base de datos XML y servicios de Atom. Usted construirá dicha aplicación usando una base de datos XML, soporte JDBC 4.0 para SQLXML, y el IBM® WebSphere® Application Server V7.0 Feature Pack para XML.

Andrew Spyker, Senior Software Engineer, IBM

Photo of Andrew SpykerComo Senior Technical Staff Member (STSM) de los equipos de desarrollo de WebSphere Application Server, Andrew Spyker se ocupa principalmente de tres áreas. Gracias a sus cinco años de experiencia a cargo del equipo de desempeño de WebSphere Application Server, es asesor del equipo de desempeño. Como arquitecto de tiempo de ejecución de SOA, es propietario de la estrategia de conducción en todos los tiempos de ejecución de WebSphere SOA, entre los cuales se centra sobre todo en la estrategia de evaluación comparativa, desempeño y consistencia de XML. Por último, Andrew ha dedicado la mayor parte de su tiempo a la creación y conducción de la estrategia de XML de la cartera de WebSphere. Recientemente, también se ha desempeñado como Chief Architect para el WebSphere Application Server XML Feature Pack.



Bert Van Der Linden, DB2 pureXML Architect, IBM

Photo of Bert Van Der LindenBert Van Der Linden comenzó a trabajar para IBM en 2001 como Architect de pureXML en DB2, período que culminó con el lanzamiento de DB2 9 en 2006. Paralelamente, se dedicó, junto con numerosos socios y clientes, a la evangelización de XML en la base de datos y sigue trabajando intensamente al lado de los clientes. Bert llegó a IBM desde una empresa incipiente denominada Propel, donde lideraba el diseño y la implementación de un middleware distribuido y tolerante al error que alojaba una aplicación escalable de e-commerce. Antes, Bert había trabajado durante muchos años para Tandem Computers en el producto NonStop SQL, una base de datos que ejecutaba muchas aplicaciones críticas en la industria financiera.



29-07-2011 (Primera publicación 05-05-2010)

31 de marzo de 2010 -Se han agregado vínculos con tres videos al comienzo de la sección Recursos.

Ejemplo de aplicación: Verificador de blogs con integración de bases de datos

Considere la siguiente aplicación Web.

Figura 1. Verificador de blogs con integración de bases de datos
Verificador de blogs con integración de bases de datos

Esta aplicación Web funciona con datos de blogs expuestos en servicios web de blogs. Los datos, que contienen información sobre todos los blogs propiedad de un blogger y todos los comentarios sobre estos blogs, son devueltos en forma de datos Atom XML (ver Listado 1 a modo de ejemplo). La aplicación Web permite que el blogger rápidamente consulte los comentarios incluidos en sus blogs y elimine los comentarios con contenidos cuestionables. La aplicación Web muestra los datos en formatos y páginas Web XHTML. Dado que los datos se encuentran en formato XML en la fuente y que los datos del navegador también tienen formato XML (HTML o XHTML), resulta natural trabajar con datos que son originalmente XML.

Listado 1. Ejemplo de feed de un comentario en Atom XML
<?xml version="1.0"
                encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom">
                <title type="text">WebSphere Community Blog</title> ...
                <entry>
   <id>tag:blogger.com,1999:blog-1417695962027703953.post-6498982274841848264</id>
                <published>2009-10-17T13:06:00.000-05:00</published>
                <updated>2009-10-17T13:06:00.000-05:00</updated>
                <atom:title xmlns="" xmlns:atom="http://www.w3.org/2005/Atom"
                type="text"> Questionable spamming comment title </atom:title>
                <atom:content xmlns="" xmlns:atom="http://www.w3.org/2005/Atom"
                type="html"> Questionable spamming comment content
                </atom:content> ... <atom:author xmlns=""
                    xmlns:atom="http://www.w3.org/2005/Atom"> <atom:name>Joe
                    Smith</atom:name>
                    <atom:uri>http://joe.uri.com</atom:uri>
                    <atom:email>jsmith@email.com</atom:email>
                    </atom:author> </entry> ...
                </feed>

Con el tiempo, es probable que el blogger descubra que los comentarios cuestionables tienen su origen en los mismos usuarios o el mismo nombre de dominio (como se observa en el elemento atom:author del Listado 1). En este memento, se actualiza la aplicación para permitir que el blogger, al eliminar un comentario, indique a un usuario o dominio como generador de spams. Esta información no se almacena en el servicio web del comentario original, por lo cual debe persistir a un almacén de datos. Como los datos ya se encuentran en formato XML, resulta natural persistirlos a una base de datos XML. Esto permite la futura utilización de la aplicación para informar estadísticas sobre generadores de spam específicos y brindar recomendaciones sobre cuáles son los comentarios que se deberán eliminar.

¿Cuál es la mejor manera de implementar la aplicación?

En el pasado, antes de que las bases de datos fueran compatibles con XML desde su origen, existían dos maneras típicas de trabajar con datos XML.En primer lugar, se podían serializar los datos en una cadena y luego almacenarlos en la base de datos como un character large object (CLOB). Este enfoque presenta problemas de rendimiento y no permite que los datos sean consultados dentro de la base de datos como XML.

Siglas usadas frecuentemente

  • API: Application program interface (Interfaz de programación de aplicaciones)
  • DOM: Document Object Model (Modelo en Objetos para la representación de Documentos)
  • HTML: Hypertext Markup Language (lenguaje de marcado de hipertexto)
  • HTTP: Hypertext Transfer Protocol (Protocolo de transferencia de hipertexto)
  • JAXP: Java for XML Processing (Java para procesamiento de XML)
  • JDBC: Java Database Connectivity (Conectividad de bases de datos Java)
  • SAX: Simple API for XML (API simple para XML)
  • SOA: Service-oriented architecture (Arquitectura orientada a servicios)
  • SQL: Structured Query Language (Lenguaje estructurado de consulta)
  • URI: Uniform Resource Identifier (Identificador uniforme de recursos)
  • URL: Uniform Resource Locator (Localizador uniforme de recursos)
  • W3C: World Wide Web Consortium
  • WSDL: Web Services Description Language (Lenguaje de descripción de servicios web)
  • XHTML: Extensible Hypertext Markup Language (lenguaje extensible de marcado de hipertexto)
  • XML: Extensible Markup Language (Lenguaje de marcado extensible)
  • XSLT: Extensible Stylesheet Language Transformations (Transformaciones XSL)

En segundo lugar, se podía descomponer los datos o el mapa en tablas relacionales que representan a grandes rasgos la estructura de los datos XML. Este enfoque presenta problemas de fidelidad debido a la falta de correspondencia entre cómo se representan los datos relacionales y los datos XML, exige que el usuario mantenga un código para el mapeo, y tampoco permite las consultas en los XML originales. Más aún, debido a que los nuevos requerimientos impulsan cambios en el esquema de datos XML, el cambio del mapeo relacional se vuelve por lo general muy difícil.

Dado el crecimiento de XML en la empresa, las bases de datos han comenzado a almacenar datos no sólo relacionales, sino también XML. Para XML, la base de datos almacena los datos en su origen en columnas XML. Algunas de las bases de datos que soportan columnas XML columnas son Apache Derby, IBM DB2®, Oracle Database, y Microsoft® SQLServer.

Además, la obtención de datos del nivel medio presentaba en el pasado numerosos desafíos. Antes de JDBC 4.0, las principales opciones consistían en usar los tipos de datos String o CLOB. Como se mencionara anteriormente, estos tipos generan problemas de rendimiento debido a la necesidad de serializar los datos. También, por lo general requerían extensiones SQL no estándar para poder comprender el modo de analizar los datos en una columna XML. JDBC 4.0 introdujo un soporte estandarizado para el tipo SQLXML que permite la lectura y la escritura de XML en la base de datos en formato XML. JDBC 4.0 permite el acceso a los datos XML a través de cadenas, flujos de lectora y escritora o fuentes y resultados JAXP. Este soporte de significa que los XML pueden pasar en su estado original por el nivel medio y la base de datos sin mapeos innecesarios ni sobrecargas al rendimiento en la base de datos o el nivel medio.

Ejemplo simple del uso de JDBC 4.0 para obtener datos XML

Examinemos un ejemplo que usa el soporte de JDBC 4.0. La lectura de datos XML en JDBC 4.0 es similar al trabajo con otros tipos de datos.

Los pasos básicos para leer datos XML son:

  1. Crear un enunciado preparado.
  2. Ejecutar el enunciado preparado para obtener un conjunto de resultados.
  3. Obtener un objeto SQLXML del conjunto de resultados.
  4. Leer el objeto SQLXML mediante uno de los métodos de obtención compatibles.
  5. Liberar el objeto SQLXML.

A continuación presentamos un ejemplo muy básico:

Listado 2. Lectura de datos XML con JDBC 4.0
PreparedStatement ps =
dbConnection.prepareStatement("SELECT somexmlcolumn FROM somexmltable"); ResultSet
                result = ps.executeQuery(); result.next(); SQLXML xml =
                result.getSQLXML("somexmlcolumn"); StreamSource source =
                xml.getSource(StreamSource.class); 
                // Read from the stream source xml.free();

En este ejemplo, leemos la fuente mediante un objeto de la fuente JAXP, específicamente el StreamSource. El objeto de la fuente permite que cualquier API comprenda las fuentes JAXP para poder leer los datos. El uso de la fuente StreamSource le permite usar cualquier representación que desee dentro de la memoria. Por lo general, el uso de flujos resulta más eficaz que las fuentes como DOM o SAX que generan una sobrecarga de objetos y llamadas a las API.

De modo similar, los pasos para escribir datos XML con JDBC 4.0 son:

  1. Crear un enunciado preparado.
  2. Crear un objeto SQLXML desde la conexión.
  3. Acceder al objeto SQLXML mediante uno de los métodos compatibles.
  4. Fijar el objeto SQLXML en los parámetros del enunciado.
  5. Escribir al método de acceso del objeto SQLXML.
  6. Ejecutar el enunciado.
  7. Liberar el objeto SQLXML.

A continuación presentamos un ejemplo muy básico:

Listado 3. Escritura de datos XML con JDBC 4.0
PreparedStatement ps =
     dbConnection.prepareStatement( "UPDATE somexmltable SET somexmlcolumn = ?"); SQLXML
                xml = dbConnection.createSQLXML(); StreamResult result = new
                StreamResult(xml.setBinaryStream()); ps.setSQLXML(1, xml);
                // Write to the stream
                result ps.executeUpdate(); xml.free();

Nivel medio

Como se describiera anteriormente, el valor de utilizar una base de datos XML (a diferencia de los CLOB o la descomposición de datos relacionales) es el aumento del rendimiento, la fidelidad de XML, y la simplificación del desarrollo. El rendimiento mejora debido a que los datos se guardan en un único formato en lugar de copiarse a distintos modelos de datos que, en el peor de los casos, requieren más análisis y serialización. La fidelidad de XML significa que se conserva en la base de datos la versión original sin modificaciones en lugar de una versión reconstruida y aproximada a partir de las tablas relacionales que se usan para contener a los datos XML. El desarrollo se simplifica debido a que no se requiere un código de mapeo entre los datos relacionales y los XML.

Ahora bien, consideremos el nivel medio. Al usar XML en su estado original en el nivel medio, se logran estas mismas ventajas en el nivel medio y, lo que es más importante, entre todo el nivel medio y toda la base de datos. Además, debido a que el nivel medio se conecta con más fuentes que la base de datos XML, el valor puede extenderse a otras fuentes de datos XML, como por ejemplo los feeds de servicios web.

El rendimiento de extremo a extremo mejora ya que no se realizan copias de los datos de la base de datos (u otras fuentes de datos XML) al nivel medio. Además, mejora el rendimiento en cada uno de los niveles gracias al hecho de que cada nivel puede crear la representación de XML de mayor rendimiento en le memoria al tiempo que se ofrecen modelos de programación estándar en W3C sobre la representación de los datos.

También se mantiene la fidelidad. En este ejemplo, la fidelidad de XML puede resultar un problema menor. No obstante, si se considera que los documentos que se intercambian pueden ser elementos complejos como los formularios fiscales o críticos como los informes financieros, se puede apreciar la importancia de asegurar que los datos XML se mantengan en su forma original en todos los marcos de procesamiento.

Otros marcos

Observe que otros marcos de persistencia se construyen sobre JDBC que soporta cierto tipo de datos XML en la base de datos—usualmente mediante su mapeo a la representación de un objeto. Históricamente, estos marcos tenían sus inconvenientes de rendimiento y mapeo a tablas relacionales como se describe anteriormente en ¿Cuál es la mejor manera de implementar una aplicación?. Incluso después de que estas cuestiones fueran solucionadas por las columnas XML y JDBC 4.0 SQLXML, estos marcos, cuando funcionan con datos XML en su formato original, todavía presentan ciertos inconvenientes. En primer lugar, estos marcos por lo general se mapean a la representación de un objeto que no necesariamente ese encuentra en casos en los que el usuario desea trabajar con los datos XML originales. En segundo lugar, no permiten la navegación centrada en XML, la transformación o las consultas una vez que los datos han sido mapeados a los objetos.

Por último, se logra simpleza con el uso de un único modelo de datos en todo un conjunto consistente de modelos de programación de XML. Si bien al programador Java™ en el nivel medio puede resultarle más fácil mapear objetos a DOM o JAXB para escenarios simples, estos escenarios no serán simples en el caso de los documentos de formularios fiscales antes mencionados. También, el usuario necesitará aprender no sólo JDBC y XML, sino también otros modelos de programación y de consultas en XML. Al trabajar con los datos XML según recolecciones y resultados, el programador sólo debe conocer el modelo de datos XML y los estándares W3C para la navegación, la transformación y las consultas a los datos XML. Dado que XPath y XQuery ya se usan dentro de la base de datos XML para la navegación y las consultas, es muy probable que ya posea estos conocimientos.

Esta simplicidad se logra mejor si se usa un marco que maneje gran parte del trabajo de bajo nivel de recuperar datos de la fuente, manipularlos y retornarlos a la base de datos— sin la sobrecarga de trabajo de tener que hacer copias. Para hacer esto en una aplicación simple, usaremos IBM WebSphere Application Server V7.0 Feature Pack para XML. Dado que el XML Feature Pack puede manipular XML en su forma original desde la base de datos, no se produce una sobrecarga de trabajo innecesaria en el rendimiento. Además, debido a que los datos permanecen en formato XML, XML Feature Pack tiene la capacidad de navegar, transformar o consultar los datos de manera sencilla.

IBM WebSphere Application Server V7.0 Feature Pack para XML

IBM WebSphere Application Server V7.0 Feature Pack para XML introduce soporte para la navegación, transformación y consultas en XML original usando los modelos de programación XPath 2.0, XSLT 2.0, y XQuery 1.0 del estándar W3C en el nivel medio. Dada la popularidad de los datos XML en el nivel de la base de datos, deseamos aplicar el anterior enfoque JDBC 4.0 no específico del producto a XML Feature Pack con una base de datos XML como por ejemplo IBM DB2 con pureXML®, Apache Derby, o la base de datos Oracle en el siguiente formato básico:

Figura 2. Diagrama de topología simple de XML Feature Pack y la base de datos de XML
Diagrama de topología simple de XML Feature Pack y la base de datos de XML

Usted verá de qué manera una base de datos XML, el soporte de JDBC 4.0 para SQLXML, y el XML Feature Pack soportan a los datos XML en la base de datos y el nivel medio.

El escenario se encuentra disponible como muestra con código fuente en XML Feature Pack para permitirle trabajar y experimentar con sus propias aplicaciones. Podrá encontrar vínculos para descargar XML Feature Pack y Derby, además de DB2 Express en la sección Recursos.

La combinación del soporte a XML original en la base de datos, JDBC 4.0, y el XML Feature Pack permite la generación de una arquitectura directa y de alto rendimiento.

Implementación de la aplicación de muestra

Veamos de qué manera puede implementar esta aplicación con XML Feature Pack, JDBC 4.0, y una base de datos XML. En primer lugar, usted recupera los malos comentarios del blog con el servicio web del blog que devuelve un feed Atom (ver Figura 1). A medida que usted procesa los malos comentarios, usted verificará la información histórica de la base de datos para ver si el comentario provino de malos bloggers anteriores (generadores de spam). Mientras tanto, los datos permanecen en XML. Comencemos por recuperar la información sobre los comentarios del blog desde el feed Atom.

Dentro del XML Feature Pack, se cargan los datos del feed Atom mediante una conexión HTTP al servicio web del blogger, y estos datos se usan como el documento de entrada en un programa XQuery. El programa XQuery se ejecuta en el tiempo de ejecución de XML Feature Pack que se invoca con la API Java de XML Feature Pack.

Usted recupera los comentarios cuestionables del feed Atom con el siguiente enunciado XPath en el programa XQuery:

Listado 4. Enunciado XPath
declare variable $comments := (
                /atom:feed/atom:entry[atom:author/atom:name = 'Anonymous'] |
                /atom:feed/atom:entry[matches(atom:content, $my:vulgarwords, 'i')]) 
                [atom:published
                > current-dateTime() - $my:monthsAgo];

Con XPath, usted busca todos los comentarios incluidos por usuarios anónimos o que contengan vocabulario vulgar dentro de una ventana de tiempo definida por el usuario. Usted almacena todas las entradas que corresponden a estos criterios en la variable comments (comentarios).

En este momento, usted querrá ver en XQuery si el generador de spam aparece en la base de datos como alguien que ya ha generado spams en otras oportunidades (donde $i es una subconsulta de los comentarios anteriores).

Listado 5. Enunciado XQuery
 let $spammedbefore :=
                local:hasEmailHasSpammedBefore($i/atom:author/atom:email/text())

Si observamos la definición de esta función, veremos cómo se cargan los datos XML desde la base de datos.

Listado 6. Función XQuery
 declare function
  local:hasEmailHasSpammedBefore($emailaddress) as xs:boolean { let $domainName :=
substring-after($emailaddress, '@') return if ($domainName = '') then false()
else let $jdbcURI := concat('jdbc://getAuthorsWhoHaveSpammedFromDomain?',
                    $domainName) let $domainSpammers := collection($jdbcURI) return
                not(empty($domainSpammers/spammers/spammer/email[. eq $emailaddress])) };

Obtenemos el nombre del dominio de la dirección de correo electronic y luego concatenamos el valor con una consulta con nombre jdbc://getAuthorsWhoHaveSpammedFromDomain, que da como resultado un URI de recolección de XPath 2.0 de jdbc://getAuthorsWhoHaveSpammedFromDomain?DOMAINNAME.

Las recolecciones de XPath 2.0 constituyen una manera fácil de integrar secuencias de datos XML que no provienen del documento de datos de entrada principal en un programa XQuery o XSLT. La implementación de la función recolección es una implementación definida y dependiente, lo cual significa que cada tiempo de ejecución de XPath 2.0 puede proveer sus propias resoluciones de recolección predeterminadas, o permitir que los usuarios extiendan el tiempo de ejecución para proporcionar implementaciones de recolección de manera dinámica. El tiempo de ejecución de XML Feature Pack permite a los usuarios proporcionar sus propias implementaciones de recolección mediante la interfaz XCollectionResolver.

En esta muestra, implementamos una XCollectionResolver que maneja todas las recolecciones que comienzan con un esquema jdbc:// URI y resuelve el resto del URI contra un conjunto de consultas previamente definidas y nombradas. Esta resolución de recolección busca la consulta nombrada que proporcionó el usuario, anexa los parámetros de posición y ejecuta los enunciados JDBC en función de la base de datos.

En el Listado 7, usted puede ver dónde se ejemplifica esta resolución después de definir algunas consultas básicas con nombre. Además, pasamos una conexión de la base de datos al resolver, para que el éste último pueda trabajar con cualquier conexión JDBC.

Listado 7. Configuración del resolver
dbStatementsSupportsSQLXML = new
                HashMap<String,
String>(); dbStatementsSupportsSQLXML.put("getAuthorsWhoHaveSpammedFromDomain",
                    "SELECT CONTACTS from SPAMMERS where DOMAINNAME =
                ?"); dbStatementsSupportsSQLXML.put("updateAuthorsWhoHaveSpammedByDomain",
                "UPDATE SPAMMERS SET CONTACTS = ? WHERE DOMAINNAME = ?");
                dbStatementsSupportsSQLXML.put("insertAuthorsWhoHaveSpammedByDomain", 
                "INSERT INTO
                SPAMMERS (CONTACTS, DOMAINNAME) VALUES (?, ?)"); Connection conn =
                getDatabaseConnection(); JDBCCollectionResolver inputResolver = new
                JDBCCollectionResolver(conn, dbStatementsSupportsSQLXML);

En el Listado 8, usted puede ver partes de la implementación del resolver. Para ver la implementación total, consulte el código fuente de muestra de XML Feature Pack. Este resolver es básicamente el mismo que la la muestra más sencilla que se presentó anteriormente de la lectura de datos XML mediante JDBC 4.0.

Para poder ser más reutilizable, el resolver agrega lo siguiente:

  1. El resolver busca consultas con nombre suministradas desde el exterior, en lugar de definir de manera inamovible los enunciados SQL.
  2. El resolver observa el tipo de metadatos en la fila y la columna de retorno, asegurando que solamente lea columnas XML con el tipo SQLXML.
  3. Por último, el resolver usa otras dos construcciones de la API de XML Feature Pack (XSequenceCursor y XItemView) para construir una secuencia de los datos XML que son devueltos desde la consulta JDBC.
Listado 8. Implementación del resolver
 public XSequenceCursor getCollection(String
                uri, String base) { 
                // look up query from query collection provided from Listado 7
                String query = lookupNamedQuery(uri); PreparedStatement p =
                dbConnection.prepareStatement(query); 
                ResultSet rs = p.executeQuery(); ... 
                // Loop
through the result returned from the query ResultSetMetaData metadata =
rs.getMetaData(); int colType = metadata.getColumnType(jj+1); if (colType =
Types.SQLXML) { SQLXML sqlx = rs.getSQLXML(...); StreamSource source =
sqlx.getSource(StreamSource.class); XItemView item = itemFactory.item(source);
sqlx.free();} // Use the XML Feature Pack API to create a sequence from the
returned XML data ... XItemView itemView[] = items.toArray(new XItemView[0]);
                XSequenceCursor sequence = itemFact.sequence(itemView); return sequence; }

En este momento, tenemos un resolver de recolecciones bastante general para usar en cualquier programa XQuery que acepta cualquier número de datos de entrada y devuelve recolecciones de datos XML para su procesamiento con XPath 2.0, XSLT 2.0, o XQuery 1.0. A continuación presentamos otros dos ejemplos. En el primero, creamos una lista de todos los generadores de spam que usan el elemento name (nombre); en el segundo, devolvemos la cantidad de generadores de spam con más de diez registros.

Listado 9. Más ejemplos de XQuery
 Java:
                dbStatementsSupportsSQLXML.put("getAllSpammers",
                "SELECT CONTACTS from SPAMMERS");
XQuery: let $allSpammers := collection('jdbc://getAllSpammers') return for $i in
                $allspammers let $first := $i/name/first order by $i/name/last return
                <name> <first>{ $first }</first>
                <last>{ $i/name/last }</last> </name>
Java: dbStatementsSupportsSQLXML.put("getAllSpamAuthorsWhereSpamCountGreaterThan",
                "SELECT CONTACTS from SPAMMERS where COUNT > ?");
                XQuery: let $minCount := 10
                let $allSpammers := collection(concat( 'jdbc://
                getAllSpamAuthorsWhereSpamCountGreaterThan?', $minCount) ) return
                count($allSpammers) }

Además, dado que el resolver de recolecciones forma parte de XPath 2.0, resulta tan útil para XSLT 2.0 como para XQuery 1.0. A continuación presentamos un ejemplo simple de XSLT 2.0 que usa el resolver de recolecciones:

Listado 10. Más ejemplos de XSLT
<xsl:variable name="allSpammers"
                select="collection('jdbc://getAllSpammers')"/> <xsl:template
                match="/"> <p>The current spammer database contains the
                following domains and spammers.</p> <xsl:for-each
                select="$allSpammers"> <table> <tr>
                <th>Name</th><th>Email</th>
                </tr> <xsl:for-each select="$allSpammers">
                <tr> <td><xsl:value-of
                select="name"/></td> <td><xsl:value-of
                select="email"/></td> </tr>
                </xsl:for-each> </table>
                </xsl:template>

De manera similar, la escritura de datos en una base de datos XML es posible. XSLT 2.0 permite que los resultados sean escritos en múltiples documentos según lo identificado por un URI usando la instrucción xsl:result-document. Al igual que antes, la resolución de este URI depende de la implementación del tiempo de ejecución. Para permitir que los usuarios especifiquen dónde se escriben los resultados, XML Feature Pack ofrece la interfaz XResultsResolver. En este ejemplo, implementamos un resolver de resultados JDBC similar que usa enunciados con nombre y parámetros posicionales con el parámetro XML para denotar un valor centinela de —XML—.

Esto permite la escritura de datos en la base de datos como se muestra en el Listado 11:

Listado 11. Documento de resultados XSLT
<!-- Is this an insert or an update
                --> <xsl:variable name="insert"
                select="count($spammersByDomain/spammers/spammer) eq 0"/> <!-- Create
                the insert statement named query --> <xsl:variable
                name="insertJdbcURI"
                select="concat('jdbc://insertAuthorsWhoHaveSpammedByDomain?--XML--&',
                $domain)"/> <!-- Create the update statement named query -->
                <xsl:variable name="updateJdbcURI"
                select="concat('jdbc://updateAuthorsWhoHaveSpammedByDomain?--XML--&',
                $domain)"/> <!— If insert, insert the xmldoc into the database.
                Otherwise, update the database with the xmldoc. --> <xsl:template
                match="/"> <xsl:when test="$insert">
                <xsl:result-document href="{$insertJdbcURI}" method="xml"
                indent="yes"> <xsl:copy-of select="$xmldoc"/>
                </xsl:result-document> </xsl:when>
                <xsl:otherwise> <xsl:result-document href="{$updateJdbcURI}"
                method="xml" indent="yes"> <xsl:copy-of select="$xmldoc"/>
                </xsl:result-document> </xsl:otherwise>
                </xsl:template>

Cuando se ejecuta esto en el caso que el generador de spam sea nuevo (no existe un generador de spam para un dominio particular) se ejecutará la ruta de inserción de la instrucción xsl:when. En ese caso, el tiempo de ejecución de XML verá una solicitud para escribir los contenidos de la variable xmldoc en un URI de resultados de:

Listado 12. URI de resultados
jdbc://insertAuthorsWhoHaveSpammedByDomain?--XML--&domain.com

El resolver de resultados de la muestra resolverá entonces este enunciado a una consulta con nombre que hemos predefinido como:

Listado 13. Consulta con nombre
 INSERT INTO SPAMMERS (CONTACTS, DOMAINNAME) VALUES
                (?, ?)

Luego, el resolver de resultados de la muestra adjuntará los contenidos XML de la variable xmldoc al primer parámetro posicional y domain.com al segundo parámetro posicional.

Al igual que la lectura de datos XML con recolecciones, la escritura de datos XML con resultados no es exclusiva de uno de los lenguajes XML. En el ejemplo anterior de escritura, se usó XSLT (ver Listado11). Con el mismo enfoque del resolver de resultados, usted puede indicar a un programa XQuery 1.0 que escriba el resultado en una base de datos XML.

Comentario sobre el uso de un JDBC Resolver genérico en comparación con otros enfoques

El enfoque que aquí se describe, la definición de una recolección de entradas y resultados JDBC y de los resolveres de resultados en XML Feature Pack que son implementados por JDBC 4.0, constituye sólo una de las maneras de implementar una integración natural y de alto rendimiento para el XML Feature Pack y las bases de datos XML.

Como alternativa, usted podrá implementar los datos de entrada (resolver de recolecciones) como una función de extensión de XPath 2.0 definida que sea más específica como por ejemplo:

Listado 14. Función XQuery menos general
 declare function
                local:hasEmailHasSpammedBefore($emailaddress) as xs:boolean 
                { let $domainName := substring-after($emailaddress, '@')
                return if ($domainName = '') then false() 
                else
                let $domainSpammers
                := my:getAuthorsWhoHaveSpammerFromDomain($domainName) return
                not(empty($domainSpammers/spammers/spammer/email[. eq $emailaddress])) };

Este enfoque presenta el beneficio de que los datos de entrada y el resultado se definen de manera más precisa. La desventaja que presenta es que se debe escribir una función de extensión para cada consulta (en lugar de una para todas las consultas posibles) y que sólo funciona para los datos de entrada (la escritura de una función de extensión para el resultado no es natural ni posible en todos los casos). El uso del enfoque más general de recolecciones y resoluciones de resultados proporciona un manejo más consistente y natural en la mayoría de los casos.

Vale la pena señalar que el resolver de recolecciones y el resolver de resultados tratados forman parte del código de muestra del XML Feature Pack. Por lo tanto, el código presentado es una muestra. Para poder usar este código en una aplicación de producción, esperamos que usted extienda la muestra según las necesidades de su aplicación.

Este artículo simplificó los programas XML adrede para producir un artículo fácil de comprender. Como recordatorio, se puede ejecutar la muestra usando las muestras de XML Feature Pack samples y se incluye la totalidad del código fuente.

Resumen

Como se describiera en la reseña histórica, el valor de usar una base de datos XML (en comparación con los CLOB o la descomposición en datos relacionales) radica en un mayor rendimiento, la fidelidad de XML y la simplificación del desarrollo. El rendimiento mejora debido a que los datos se guardan en un único formato en lugar de copiarse a distintos modelos de datos que, en el peor de los casos, requieren más análisis y serialización. La fidelidad de XML significa que se conserva en la base de datos la versión original sin modificaciones en lugar de una versión reconstruida y aproximada a partir de las tablas relacionales que se usan para contener a los datos XML. El desarrollo se simplifica debido a que no se requiere un código de mapeo entre los datos relacionales y los XML.

Al usar XML en formato original en el nivel medio (con XML Feature Pack), usted obtiene esas mismas ventajas en el nivel medio y, lo que es más importante aún, entre todo el nivel medio y toda la base de datos. Además, debido a que el nivel medio se conecta a más fuentes que la base de datos XML, usted puede extender el valor a otras fuentes de datos XML, como por ejemplo los feeds de servicios web.

Recursos

Aprender

Obtener los productos y tecnologías

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Rational, Lotus, WebSphere
ArticleID=487560
ArticleTitle=Programación de XML en múltiples niveles: Uso de XML en el nivel medio para obtener rendimiento, fidelidad y facilidad de desarrollo
publish-date=07292011