Použijte xpath()
funkce:
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() odstraní okolní <status> tag.
Vrátí pole xml - v tomto případě s jediným prvkem:
status
xml[]
-------
{ERROR_MISSING_DATA}
Použito na váš stůl
V reakci na aktualizaci vaší otázky to může být:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Pokud jste si jisti, že na řádek je pouze jedna stavová značka, můžete jednoduše extrahovat první položku z pole:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Pokud může existovat více položek stavu:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Získáte 1-n řádků na id .
Odesílat do xml
Protože jste definovali sloupce typu text (místo xml
, potřebujete přenést do xml výslovně. Funkce xpath() očekává 2. parametry typu xml . Netypová řetězcová konstanta je vynucena na xml automaticky, ale text sloupec není. Musíte odesílat explicitně.
Toto funguje bez explicitního obsazení:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
CTE jako v mém prvním příkladu potřeby typ pro každý sloupec v "společném tabulkovém výrazu". Pokud bych nepřetypoval na konkrétní typ, typ unknown by bylo použito – což není totéž jako nezadaný řetězec . Je zřejmé, že mezi unknown není implementována žádná přímá konverze a xml . Museli byste přenášet do text první:unknown_type_col::text::xml . Je lepší přenést do ::xml hned.
Toto bylo zpřísněno s PostgreSQL 9.1 (myslím). Starší verze byly tolerantnější.
Ať tak či onak, u kterékoli z těchto metod musí být řetězec platný xml nebo obsazení (implicitní nebo explicitní) vyvolá výjimku.