PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Extraindo o valor da tag xml no PostgreSQL


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.