Verwenden Sie den xpath xpath()
Funktion:
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()
entfernt den umgebenden <status>
tag.
Gibt ein Array von xml
zurück - in diesem Fall mit einem einzigen Element:
status
xml[]
-------
{ERROR_MISSING_DATA}
Auf Ihre Tabelle angewendet
Als Antwort auf Ihre Frageaktualisierung kann dies einfach sein:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Wenn Sie sicher sind, dass es nur ein einziges Status-Tag pro Zeile gibt, können Sie einfach das erste Element aus dem Array extrahieren:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Wenn es mehrere Statuselemente geben kann:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Erhält 1-n Zeilen pro id
.
In xml
umwandeln
Da Sie Ihre Spalten als Typ text
definiert haben (anstelle von xml
, brauchen Sie in xml
umzuwandeln ausdrücklich. Die Funktion xpath()
erwartet den 2. Parameter vom Typ xml
. Eine nicht typisierte Zeichenfolgenkonstante wird in xml
umgewandelt automatisch, sondern ein text
Spalte ist nicht. Sie müssen explizit umwandeln.
Dies funktioniert ohne expliziten Cast:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
Ein CTE wie in meinem ersten Beispiel braucht einen Typ für jede Spalte im "gemeinsamen Tabellenausdruck". Wenn ich nicht auf einen bestimmten Typ gecastet hätte, wäre der Typ unknown
verwendet worden wäre - was nicht ist dasselbe wie ein nicht typisierter String . Offensichtlich gibt es keine direkte Konvertierung zwischen unknown
und xml
. Sie müssten in text
umwandeln zuerst:unknown_type_col::text::xml
. Besser in ::xml
umwandeln sofort.
Dies wurde mit PostgreSQL 9.1 verschärft (glaube ich). Ältere Versionen waren freizügiger.
Wie auch immer, bei jeder dieser Methoden muss der String valid xml sein oder die Umwandlung (implizit oder explizit) löst eine Ausnahme aus.