Използвайте xpath()
функция:
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()
премахва околния <status>
Връща масив от xml
- с един елемент в този случай:
status
xml[]
-------
{ERROR_MISSING_DATA}
Приложено към вашата маса
В отговор на актуализацията на вашия въпрос това може просто да бъде:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Ако сте сигурни, че има само един маркер за състояние на ред, можете просто да извлечете първия елемент от масива:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Ако може да има няколко елемента за състояние:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Получава ви 1-n реда на id
.
Прехвърляне към xml
Тъй като сте дефинирали вашите колони да бъдат от тип text
(вместо xml
, винатрябва за прехвърляне към xml
изрично. Функцията xpath()
очаква втория параметър от тип xml
. Нетипизирана низова константа се принуждава към xml
автоматично, но text
колоната не е. Трябва изрично да прехвърлите.
Това работи без изрично прехвърляне:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
ACTE като в първия ми пример нужди тип за всяка колона в "общия табличен израз". Ако не бях преобразувал към определен тип, типът unknown
биха били използвани - което не е същото като нетипизиран низ . Очевидно няма директно преобразуване, приложено между unknown
и xml
. Ще трябва да прехвърлите към text
първо:unknown_type_col::text::xml
. По-добре да прехвърляте към ::xml
веднага.
Това беше затегнато с PostgreSQL 9.1 (мисля). По-старите версии бяха по-разрешителни.
Така или иначе, с всеки от тези методи низът трябва да бъде валиден xml или предаването (неявно или явно) ще предизвика изключение.