Sử dụng xpath()
chức năng:
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()
dải <status>
xung quanh .
Trả về một mảng xml
- với một phần tử duy nhất trong trường hợp này:
status
xml[]
-------
{ERROR_MISSING_DATA}
Đã áp dụng cho bảng của bạn
Để trả lời cập nhật câu hỏi của bạn, điều này có thể đơn giản là:
SELECT id, xpath('./status/text()', response::xml) AS status
FROM tbl;
Nếu bạn chắc chắn chỉ có một thẻ trạng thái duy nhất trên mỗi hàng, bạn có thể chỉ cần trích xuất mục đầu tiên từ mảng:
SELECT id, (xpath('./status/text()', response::xml))[1] AS status
FROM tbl;
Nếu có thể có nhiều mục trạng thái:
SELECT id, unnest(xpath('./status/text()', response::xml)) AS status
FROM tbl;
Cho bạn 1-n hàng cho mỗi id
.
Truyền tới xml
Vì bạn đã xác định các cột của mình thuộc loại text
(thay vì xml
, bạn cần để truyền sang xml
một cách rõ ràng. Hàm xpath()
mong đợi các tham số thứ 2 của loại xml
. Hằng số chuỗi không định kiểu được ép buộc thành xml
tự động, nhưng là text
cột không phải. Bạn cần truyền một cách rõ ràng.
Điều này hoạt động mà không có diễn viên rõ ràng:
SELECT xpath('./status/text()'
,'<?xml version="1.0" ?><response><status>SUCCESS</status></response>')
Đ CTE như trong ví dụ đầu tiên của tôi nhu cầu một kiểu cho mọi cột trong "biểu thức bảng chung". Nếu tôi không truyền đến một loại cụ thể, thì loại unknown
lẽ ra đã được sử dụng - mà không phải điều tương tự như một chuỗi không định kiểu . Rõ ràng, không có chuyển đổi trực tiếp nào được thực hiện giữa unknown
và xml
. Bạn phải truyền tới text
đầu tiên:unknown_type_col::text::xml
. Tốt hơn nên truyền sang ::xml
ngay lập tức.
Điều này đã được thắt chặt với PostgreSQL 9.1 (tôi nghĩ). Các phiên bản cũ dễ dãi hơn.
Dù bằng cách nào, với bất kỳ phương thức nào trong số này, chuỗi phải là xml hợp lệ hoặc dàn diễn viên (ẩn hoặc rõ ràng) sẽ đưa ra một ngoại lệ.