Usa xpath()
funzione:
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() rimuove il <status> circostante tag.
Restituisce un array di xml - con un solo elemento in questo caso:
status
xml[]
-------
{ERROR_MISSING_DATA}
Applicato al tuo tavolo
In risposta all'aggiornamento della tua domanda, questo può essere semplicemente:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Se sei certo che esiste un solo tag di stato per riga, puoi semplicemente estrarre il primo elemento dall'array:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Se possono essere presenti più elementi di stato:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Ottieni 1-n righe per id .
Trasmetti su xml
Poiché hai definito le tue colonne di tipo text (invece di xml
, hai necessità per trasmettere a xml esplicitamente. La funzione xpath() attende il 2° parametro di tipo xml . Una costante stringa non tipizzata viene forzata a xml automaticamente, ma un text colonna non è. Devi trasmettere in modo esplicito.
Funziona senza un cast esplicito:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
Un CTE come nel mio primo esempio esigenze un tipo per ogni colonna nell'"espressione di tabella comune". Se non avessi eseguito il cast a un tipo specifico, il tipo unknown sarebbe stato utilizzato, il che non la stessa cosa di una stringa non tipizzata . Ovviamente, non è stata implementata alcuna conversione diretta tra unknown e xml . Dovresti trasmettere a text primo:unknown_type_col::text::xml . Meglio trasmettere a ::xml subito.
Questo è stato rafforzato con PostgreSQL 9.1 (credo). Le versioni precedenti erano più permissive.
Ad ogni modo, con uno qualsiasi di questi metodi la stringa deve essere xml valido o il cast (implicito o esplicito) solleverà un'eccezione.