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.