Use o
xpath()
função: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()
remove o <status>
circundante tag.Retorna um array de
xml
- com um único elemento neste caso:status
xml[]
-------
{ERROR_MISSING_DATA}
Aplicado à sua mesa
Em resposta à atualização da sua pergunta, isso pode ser simplesmente:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Se tiver certeza de que há apenas uma única tag de status por linha, você pode simplesmente extrair o primeiro item da matriz:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Se pode haver vários itens de status:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Obtém 1 n linhas por
id
. Transmitir para xml
Como você definiu suas colunas como do tipo
text
(em vez de xml
, você precisa para transmitir para xml
explicitamente. A função xpath()
espera os 2º parâmetros do tipo xml
. Uma constante de string não tipada é forçada a xml
automaticamente, mas um text
coluna não é. Você precisa converter explicitamente. Isso funciona sem conversão explícita:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
Um CTE como no meu primeiro exemplo necessidades um tipo para cada coluna na "expressão de tabela comum". Se eu não tivesse convertido para um tipo específico, o tipo
unknown
teria sido usado - o que não a mesma coisa que uma string não digitada . Obviamente, não há conversão direta implementada entre unknown
e xml
. Você teria que transmitir para text
primeiro:unknown_type_col::text::xml
. Melhor transmitir para ::xml
agora mesmo. Isso foi reforçado com o PostgreSQL 9.1 (eu acho). As versões mais antigas eram mais permissivas.
De qualquer forma, com qualquer um desses métodos, a string deve ser xml válido ou o cast (implícito ou explícito) levantará uma exceção.