El alcance del post es cargar, leer, actualizar y transformar datos desde y hacia XML dentro de la base de datos, por lo tanto, no incluye ningún tipo de operaciones desde un provider o driver hacia arriba.
Motor: Oracle
Versión Mínima: Oracle9i release 1 (9.0.1)
Fuente: http://download.oracle.com/docs/cd/B...b14259/toc.htm
1. Empezamos con un pequeño fichero XML almacenado en disco.
Código:
2. Creación de la tabla, con un identificador y una columna del tipo XMLType.oracle@buo:~/scripts/xml> more data.xml <?xml version='1.0' encoding='UTF-8' ?> <root> <entity> <id>1</id> <f_name>nombre_1</f_name> <l_name>apellido_1</l_name> <dni>dni_1</dni> </entity> <entity> <id>2</id> <f_name>nombre_2</f_name> <l_name>apellido_2</l_name> <dni>dni_2</dni> </entity> <entity> <id>3</id> <f_name>nombre_3</f_name> <l_name>apellido_3</l_name> <dni>dni_3</dni> </entity> </root>
Código:
3. Para la carga del fichero, opté por hacerlo vía SQL o PL/SQL.SQL> create table t1 2 (id number(8), 3 xml_data XMLType) 4 / Table created.
Código:
4. Los ejemplos básicos de XQuery y XPath, en primer lugar un select del texto que contiene el Elemento L_NAME dentro del XPath root/entity[1]/l_name, en segundo lugar, la misma función pero dentro de un WHERESQL> create directory xmldir as '/home/oracle/scripts/xml' 2 / Directory created. SQL> insert into t1 values (1,XMLType(bfilename('XMLDIR','data.xml'),nls_charset_id('UTF8'))); 1 row created. SQL> select id, xml_data from t1; ID ---------- XML_DATA ----------------------------------------- 1 <?xml version="1.0" encoding="US-ASCII"?> <root> <entity> <id>1</id> <f_name>nombre_1</f_name> <l_name>apellido_1</l_name> <dni>dni_1</dni> </entity> <entity> <id>2</id> <f_name>nombre_2</f_name> <l_name>apellido_2</l_name> <dni>dni_2</dni> </entity> <entity> <id>3</id> <f_name>nombre_3</f_name> <l_name>apellido_3</l_name> <dni>dni_3</dni> </entity> </root>
Código:
5. Función muy útil para evaluar la existencia de un Elemento, existsNode devuelve un 1 por true y 0 por false.SQL> select extractValue(xml_data,'root/entity[1]/l_name') from t1; EXTRACTVALUE(XML_DATA,'ROOT/ENTITY[1]/L_NAME') -------------------------------------------------------------------------------- apellido_1 SQL> select id from t1 2 where extractValue(xml_data,'root/entity[2]/l_name') = 'apellido_2'; ID ---------- 1
Código:
6. Actualizar el texto dentro del Elemento L_NAME en la primera posición de la colección de Elementos Entity, aquí mismo es donde se empieza a notar la potencia de XML DB, dado que en una sola sentencia SQL podemos actualizar un nodo dentro de un XML en un registro de una tabla, antes, debíamos extraer todo el XML, hacerlo pasar por una capa de acceso a datos, parsearlo mediante código, actualizar el valor y guardar nuevamente el XML en la base de datos.SQL> select count(*) from t1 2 where existsNode(xml_data,'root/entity/l_name') = 1; COUNT(*) ---------- 1
Código:
7. Vamos por el paso inverso, transformar una tabla estándar con varias columnas al formato XML.SQL> update t1 2 set xml_data = updateXML(xml_data,'root/entity[1]/l_name/text()','apellido_11') 3 where extractValue(xml_data,'root/entity[1]/l_name') = 'apellido_1'; 1 row updated. SQL> select id, xml_data from t1; ID ---------- XML_DATA -------------------------------------------------------------------------------- 1 <?xml version="1.0" encoding="US-ASCII"?> <root> <entity> <id>1</id> <f_name>nombre_1</f_name> <l_name>apellido_11</l_name> <dni>dni_1</dni> </entity> <entity> <id>2</id> <f_name>nombre_2</f_name> <l_name>apellido_2</l_name> <dni>dni_2</dni> </entity> <entity> <id>3</id> <f_name>nombre_3</f_name> <l_name>apellido_3</l_name> <dni>dni_3</dni> </entity> </root>
Código:
7.1 Formato XML donde cada columna esta representada como atributos.SQL> create table t2 2 (id number(8), 3 f_name varchar2(30), 4 l_name varchar2(30), 5 dni varchar2(30) 6 ) 7 / Table created. SQL> insert into t2 values (1,'nombre_1','apellido_1','dni_1') 2 / 1 row created. SQL> insert into t2 values (2,'nombre_2','apellido_2','dni_2') 2 / 1 row created. SQL> insert into t2 values (3,'nombre_3','apellido_3','dni_3') 2 / 1 row created.
Código:
7.2 Formato XML donde cada columna esta representada como elementos.SQL> select XMLElement("Entity", XMLAttributes( 2 id as "ID", 3 f_name as "F_NAME", 4 l_name as "L_NAME", 5 dni as "DNI")) 6 as xml 7 from t2; XML ------------------------------------------------------------------------------ <Entity ID="1" F_NAME="nombre_1" L_NAME="apellido_1" DNI="dni_1"></Entity> <Entity ID="2" F_NAME="nombre_2" L_NAME="apellido_2" DNI="dni_2"></Entity> <Entity ID="3" F_NAME="nombre_3" L_NAME="apellido_3" DNI="dni_3"></Entity>
Código:
La construccion del fichero XML queda a gusto de cada uno, hay muchos post donde se comenta como transformar un resultset a fichero. SQL> select XMLElement("Entity",XMLForest(id, f_name, l_name, dni)) as xml from t2; XML ---------------------------------------------------------------------------------------------------- <Entity><ID>1</ID><F_NAME>nombre_1</F_NAME><L_NAME>apellido_1</L_NAME><DNI>dni_1</DNI></Entity> <Entity><ID>2</ID><F_NAME>nombre_2</F_NAME><L_NAME>apellido_2</L_NAME><DNI>dni_2</DNI></Entity> <Entity><ID>3</ID><F_NAME>nombre_3</F_NAME><L_NAME>apellido_3</L_NAME><DNI>dni_3</DNI></Entity>