El módulo xml2 proporciona consultas XPath y
funcionalidad XSLT.
A partir de PostgreSQL 8.3, existe en el servidor central
funcionalidad relacionada con XML basada en el estándar SQL/XML.
Esa funcionalidad cubre la comprobación de sintaxis XML y consultas XPath,
que es lo que hace este módulo, y más, pero la API no es compatible
en absoluto. Está previsto que este módulo sea eliminado en una versión
futura de PostgreSQL a favor de la nueva API estándar, por lo que
se te anima a intentar convertir tus aplicaciones. Si encuentras
que alguna de la funcionalidad de este módulo no está disponible
de forma adecuada con la nueva API, por favor explica tu problema a
<[email protected]> para que se pueda abordar esa deficiencia.
La tabla Table F.37 muestra las funciones proporcionadas por este módulo. Estas funciones ofrecen un análisis de XML y consultas XPath sencillos.
Table F.37. Funciones de xml2
Función Descripción |
|---|
Analiza el documento proporcionado y devuelve true si el
documento es un XML bien formado. (Nota: este es un alias para la función estándar
de PostgreSQL |
Evalúa la consulta XPath en el documento proporcionado y
convierte el resultado a |
Evalúa la consulta XPath en el documento proporcionado y
convierte el resultado a |
Evalúa la consulta XPath en el documento proporcionado y
convierte el resultado a |
Evalúa la consulta en el documento y envuelve el resultado en etiquetas XML. Si el resultado es de múltiples valores, la salida se verá como: <toptag> <itemtag>Valor 1 que podría ser un fragmento XML</itemtag> <itemtag>Valor 2....</itemtag> </toptag>
Si |
Como |
Como |
Evalúa la consulta en el documento y devuelve múltiples valores
separados por el separador especificado, por ejemplo |
Este es un envoltorio para la función anterior que utiliza |
xpath_table #xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
xpath_table es una función de tabla que evalúa un conjunto de consultas XPath
en cada uno de un conjunto de documentos y devuelve los resultados como una
tabla. El campo de clave primaria de la tabla de documentos original se devuelve
como la primera columna del resultado para que el conjunto de resultados
se pueda utilizar fácilmente en uniones (joins). Los parámetros se describen en
Table F.38.
Table F.38. Parámetros de xpath_table
| Parámetro | Descripción |
|---|---|
key |
el nombre del campo “clave” — este es solo un campo para ser utilizado como la primera columna de la tabla de salida, es decir, identifica el registro del cual proviene cada fila de salida (ver nota más abajo sobre resultados con múltiples valores) |
document |
el nombre del campo que contiene el documento XML |
relation |
el nombre de la tabla o vista que contiene los documentos |
xpaths |
una o más expresiones XPath, separadas por |
criteria |
el contenido de la cláusula WHERE. Esto no se puede omitir, por lo que debes usar
|
Estos parámetros (excepto las cadenas XPath) simplemente se sustituyen en una sentencia SQL SELECT normal, por lo que tienes cierta flexibilidad — la sentencia es
SELECT <key>, <document> FROM <relation> WHERE <criteria>
por lo que esos parámetros pueden ser cualquier cosa válida en esas ubicaciones particulares. El resultado de este SELECT necesita devolver exactamente dos columnas (lo cual hará a menos que intentes listar múltiples campos para la clave o el documento). Ten en cuenta que este enfoque simplista requiere que valides cualquier valor proporcionado por el usuario para evitar ataques de inyección SQL.
La función tiene que ser utilizada en una expresión FROM, con una
cláusula AS para especificar las columnas de salida; por ejemplo
SELECT * FROM
xpath_table('article_id',
'article_xml',
'articles',
'/article/author|/article/pages|/article/title',
'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);
La cláusula AS define los nombres y tipos de las columnas en la
tabla de salida. La primera es el campo “clave” y el resto corresponden
a las consultas XPath.
Si hay más consultas XPath que columnas de resultado,
las consultas adicionales serán ignoradas. Si hay más columnas de resultado
que consultas XPath, las columnas adicionales serán NULL.
Ten en cuenta que este ejemplo define la columna de resultado page_count
como un entero. La función trabaja internamente con representaciones de cadena,
por lo que cuando indicas que quieres un entero en la salida, tomará la
representación de cadena del resultado XPath y usará las funciones de entrada de
PostgreSQL para transformarla en un entero (o en cualquier tipo que solicite la
cláusula AS). Se producirá un error si no puede hacer esto — por
ejemplo, si el resultado está vacío — por lo que es posible que desees limitarte a
usar text como tipo de columna si crees que tus datos pueden tener algún problema.
La sentencia SELECT invocadora no tiene que ser necesariamente solo
SELECT * — puede hacer referencia a las columnas de salida
por nombre o unirlas con otras tablas. La función produce una
tabla virtual con la que puedes realizar cualquier operación que desees (por ejemplo,
agregación, unión, ordenación, etc.). Así que también podríamos tener:
SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
'/article/title|/article/author/@id',
'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
AS t(article_id integer, title text, author_id integer),
tblPeopleInfo AS p
WHERE t.author_id = p.person_id;
como un ejemplo más complicado. Por supuesto, podrías envolver todo esto en una vista para mayor comodidad.
La función xpath_table asume que los resultados de cada consulta XPath
pueden ser de múltiples valores, por lo que el número de filas devueltas por la función
puede no ser el mismo que el número de documentos de entrada. La primera fila
devuelta contiene el primer resultado de cada consulta, la segunda fila el
segundo resultado de cada consulta. Si una de las consultas tiene menos valores
que las otras, se devolverán valores nulos en su lugar.
En algunos casos, un usuario sabrá que una consulta XPath dada devolverá solo un resultado único (tal vez un identificador de documento único) — si se usa junto con una consulta XPath que devuelve múltiples resultados, el resultado de valor único aparecerá solo en la primera fila del resultado. La solución para esto es usar el campo clave como parte de una unión con una consulta XPath más simple. Como ejemplo:
CREATE TABLE test (
id int PRIMARY KEY,
xml text
);
INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');
INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');
SELECT * FROM
xpath_table('id','xml','test',
'/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num
id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
1 | C1 | L1 | 1 | 2 | 3
1 | | L2 | 11 | 22 | 33
Para obtener doc_num en cada línea, la solución es utilizar dos invocaciones
de xpath_table y unir los resultados:
SELECT t.*,i.doc_num FROM
xpath_table('id', 'xml', 'test',
'/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
'true')
AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;
id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
1 | L1 | 1 | 2 | 3 | C1
1 | L2 | 11 | 22 | 33 | C1
(2 rows)
Las siguientes funciones están disponibles si libxslt está instalado:
xslt_process #xslt_process(text document, text stylesheet, text paramlist) returns text
Esta función aplica la hoja de estilo XSL al documento y devuelve el resultado transformado. La lista de parámetros paramlist es una lista de asignaciones de parámetros que se utilizarán en la transformación, especificada en el formato a=1,b=2. Ten en cuenta que el análisis de parámetros es muy simple: ¡los valores de los parámetros no pueden contener comas!
También existe una versión de dos parámetros de xslt_process que
no pasa ningún parámetro a la transformación.
John Gray <[email protected]>
El desarrollo de este módulo fue patrocinado por Torchbox Ltd. (www.torchbox.com). Tiene la misma licencia BSD que PostgreSQL.