F.50. xml2 — consultas XPath y funcionalidad XSLT #

F.50.1. Aviso de obsolescencia
F.50.2. Descripción de funciones
F.50.3. xpath_table
F.50.4. Funciones XSLT
F.50.5. Autor

El módulo xml2 proporciona consultas XPath y funcionalidad XSLT.

F.50.1. Aviso de obsolescencia #

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 para que se pueda abordar esa deficiencia.

F.50.2. Descripción de funciones #

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

xml_valid ( document text ) → boolean

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 xml_is_well_formed(). El nombre xml_valid() es técnicamente incorrecto ya que la validez y la buena formación tienen diferentes significados en XML).

xpath_string ( document text, query text ) → text

Evalúa la consulta XPath en el documento proporcionado y convierte el resultado a text.

xpath_number ( document text, query text ) → real

Evalúa la consulta XPath en el documento proporcionado y convierte el resultado a real.

xpath_bool ( document text, query text ) → boolean

Evalúa la consulta XPath en el documento proporcionado y convierte el resultado a boolean.

xpath_nodeset ( document text, query text, toptag text, itemtag text ) → text

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 toptag o itemtag es una cadena vacía, se omite la etiqueta correspondiente.

xpath_nodeset ( document text, query text, itemtag text ) → text

Como xpath_nodeset(document, query, toptag, itemtag) pero el resultado omite toptag.

xpath_nodeset ( document text, query text ) → text

Como xpath_nodeset(document, query, toptag, itemtag) pero el resultado omite ambas etiquetas.

xpath_list ( document text, query text, separator text ) → text

Evalúa la consulta en el documento y devuelve múltiples valores separados por el separador especificado, por ejemplo Valor 1,Valor 2,Valor 3 si separator es ,.

xpath_list ( document text, query text ) → text

Este es un envoltorio para la función anterior que utiliza , como separador.


F.50.3. 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ámetroDescripció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 true o 1=1 si deseas procesar todas las filas en la relación


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.

F.50.3.1. Resultados con múltiples valores #

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)

F.50.4. Funciones XSLT #

Las siguientes funciones están disponibles si libxslt está instalado:

F.50.4.1. 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.

F.50.5. Autor #

John Gray

El desarrollo de este módulo fue patrocinado por Torchbox Ltd. (www.torchbox.com). Tiene la misma licencia BSD que PostgreSQL.