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.