Use el xpath()
función:
WITH x(col) AS (SELECT '<?xml version="1.0" ?><response><status>ERROR_MISSING_DATA</status></response>'::xml)
SELECT xpath('./status/text()', col) AS status
FROM x
/text() quita el <status> circundante etiqueta.
Devuelve una matriz de xml - con un solo elemento en este caso:
status
xml[]
-------
{ERROR_MISSING_DATA}
Aplicado a tu mesa
En respuesta a la actualización de su pregunta, esto puede ser simplemente:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Si está seguro de que solo hay una etiqueta de estado por fila, simplemente puede extraer el primer elemento de la matriz:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Si puede haber varios elementos de estado:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Obtiene de 1 a n filas por id .
Transmitir a xml
Dado que definió sus columnas para que sean del tipo text (en lugar de xml
, usted necesita para convertir a xml explícitamente. La función xpath() espera los segundos parámetros de tipo xml . Una constante de cadena sin tipo se coacciona a xml automáticamente, pero un text columna no es. Necesitas lanzar explícitamente.
Esto funciona sin conversión explícita:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
Un CET como en mi primer ejemplo necesidades un tipo para cada columna en la "expresión de tabla común". Si no hubiera emitido a un tipo específico, el tipo unknown se habría utilizado, lo cual no lo mismo que una cadena sin tipo . Obviamente, no hay una conversión directa implementada entre unknown y xml . Tendrías que enviar a text primero:unknown_type_col::text::xml . Mejor convertir a ::xml enseguida.
Esto se ha reforzado con PostgreSQL 9.1 (creo). Las versiones anteriores eran más permisivas.
De cualquier manera, con cualquiera de estos métodos, la cadena debe ser xml válido o la conversión (implícita o explícita) generará una excepción.