PostgreSQL xử lý chuỗi với xpath

Table of Contents

PostgreSQL xử lý chuỗi với xpath

Tôi có bảng thế này

image

Giờ tôi cần tách theo cấu trúc thế này

image

Với cột định nghĩa cần cực kỳ ngắn gọn, 1 cụm từ thôi càng tốt

Cột description trên kia thì lại quá dài

Tách chuỗi với xpath

Ví dụ

WITH x(col) AS (SELECT '<?xml version="1.0" ?><response><h1>abbatial</h1><h3><i>əbeiʃəl</i></h3><h2>tính từ</h2><ul><li>(thuộc) trưởng tu viện</li></ul></response>'::xml)
SELECT (xpath('.//h3/i/text()', col))::text AS status
FROM   x

Giờ cần biến html từ html thành xml

Tạo cột xml

image

-- test gép chuỗi ra cấu trúc xml
SELECT '<?xml version="1.0" ?><response>' || html || '</response>'
FROM av
LIMIT 10;
-- Update cột xml
UPDATE av
SET xml = '<?xml version="1.0" ?><response>' || html || '</response>';

image

Tách giá trị với xpath

Lỗi xmlParseEntityRef: no name

image

https://stackoverflow.com/questions/7604436/xmlparseentityref-no-name-warnings-while-loading-xml-into-a-php-file

Replace & with %26

UPDATE av
SET xml = REPLACE(xml, '&', '%26' );

https://www.postgresqltutorial.com/postgresql-string-functions/postgresql-replace/

Tách giá trị với xpath

-- get pronounce
SELECT (xpath('./h3/i/text()', xml::xml))::text AS status
FROM av
LIMIT 10;

-- get def
SELECT (xpath('./ul/li/text()', xml::xml))::text AS status
FROM av
LIMIT 10;

image

Get only text

SELECT (xpath('./ul/li/text()', xml::xml))[1]::text AS status
FROM av
LIMIT 10;

image

https://openequella.github.io/tutorials/reporting/postgres/QueryingXMLType.html

Update dữ liệu def_v1

Do một số giá trị chứa ký tự đặc biệt như <> nên lỗi xml. Do vậy chạy update toàn bộ sẽ bị lỗi và thoát.
Vì vậy viết script php chạy loop, lỗi thì bỏ qua

$sql="SELECT id FROM av;";
    $query=pg_query($dbcon,$sql);
    while($kq=pg_fetch_assoc($query)){
        //echo $kq['id'];

        $sql1="UPDATE av SET def_v1 = (xpath('./ul/li/text()', xml::xml))[1] Where id = ".$kq['id'].";";
        //echo $sql1;
        //echo '<br>';
        try {
            $query2=pg_query($dbcon,$sql1);
        }

        catch(Exception $e){
            echo $sql1;
            echo '<br>';
        }
    }

Chuẩn hóa lại dữ liệu

-- Ví dụ
SELECT split_part('ordno-#-orddt-#-ordamt', '-#-', 3);

-- Tach lay 1 dinh nghia
SELECT split_part(def_v1, ', ', 1)
FROM av
LIMIT 50;

UPDATE av
SET def_v2 = split_part(def_v1, ', ', 1);

-- Tach lay dinh nghia sau dau :
SELECT split_part(def_v2, ': ', 2)
FROM av
WHERE "def_v2" ILIKE '%: %' LIMIT 50;

-- Tach lay dinh nghia truoc dau (
-- pico giây (một phần triệu triệu (10 - 12) của một giây)
SELECT split_part(def_v2, ' (', 1)
FROM av
WHERE "def_v2" ILIKE '% (%'
LIMIT 50;

-- Tach lay dinh nghia sau dau )
-- (từ lóng) người nghiện rượu
SELECT split_part(def_v2, ') ', 2)
FROM av
WHERE "def_v2" ILIKE '%) %'
LIMIT 50;

-- Tach lay dinh nghia trước dấu ;
-- dẻo; dễ nặn
SELECT split_part(def_v2, '; ', 1)
FROM av
WHERE "def_v2" ILIKE '%; %'
LIMIT 50;

-- Tach lay dinh nghia trước dấu *
-- trước 13 tuổi* danh từ
SELECT split_part(def_v2, '* ', 1)
FROM av
WHERE "def_v2" ILIKE '%* %'
LIMIT 50;

UPDATE av
SET def_v2 = split_part(def_v2, '* ', 1)
WHERE "def_v2" ILIKE '%* %';

-- Tach lay dinh nghia con chua (
-- (từ cổ; (:
SELECT * FROM "av" WHERE "def_v2" ILIKE '%(%' LIMIT 50

UPDATE av
SET def_v2 = NULL
WHERE "def_v2" ILIKE '%(%';

Leave a Reply

Your email address will not be published. Required fields are marked *