2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.50. xml2 — XPath 查詢和 XSLT 功能 #

名為 xml2 的模組提供了 XPath 查詢和 XSLT 功能。

F.50.1. 棄用宣告 #

PostgreSQL 8.3 開始,核心伺服器中提供了基於 SQL/XML 標準的 XML 相關功能。這些功能涵蓋了 XML 語法檢查和 XPath 查詢,這正是本模組的功能,並且功能更強大,但 API 完全不相容。計劃在未來的 PostgreSQL 版本中移除本模組,轉而使用新的標準 API,因此鼓勵您嘗試轉換您的應用程式。如果您發現本模組的某些功能在新 API 中沒有得到充分支援,請將您的問題告知 ,以便改進這些不足之處。

F.50.2. 函式說明 #

表 F.37 列出了本模組提供的函式。這些函式提供直接的 XML 解析和 XPath 查詢。

表 F.37. xml2 函式

函式

描述

xml_valid ( document text ) → boolean

解析給定的文件,如果文件是格式正確的 XML,則返回 true。(注意:這是標準 PostgreSQL 函式 xml_is_well_formed() 的一個別名。函式名 xml_valid() 從技術上講不正確,因為在 XML 中,有效性和格式良好性具有不同的含義。)

xpath_string ( document text, query text ) → text

在提供的文件上評估 XPath 查詢,並將結果轉換為 text 型別。

xpath_number ( document text, query text ) → real

在提供的文件上評估 XPath 查詢,並將結果轉換為 real 型別。

xpath_bool ( document text, query text ) → boolean

在提供的文件上評估 XPath 查詢,並將結果轉換為 boolean 型別。

xpath_nodeset ( document text, query text, toptag text, itemtag text ) → text

在文件上評估查詢並將結果包裝在 XML 標籤中。如果結果是多值的,輸出將如下所示:

<toptag>
<itemtag>Value 1 which could be an XML fragment</itemtag>
<itemtag>Value 2....</itemtag>
</toptag>

如果 toptagitemtag 為空字串,則相應的標籤將被省略。

xpath_nodeset ( document text, query text, itemtag text ) → text

類似於 xpath_nodeset(document, query, toptag, itemtag),但結果省略了 toptag

xpath_nodeset ( document text, query text ) → text

類似於 xpath_nodeset(document, query, toptag, itemtag),但結果省略了兩個標籤。

xpath_list ( document text, query text, separator text ) → text

在文件上評估查詢,並返回由指定分隔符分隔的多個值,例如,如果 separator,,則返回 Value 1,Value 2,Value 3

xpath_list ( document text, query text ) → text

這是上面函式的包裝器,它使用 , 作為分隔符。


F.50.3. xpath_table #

xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record

xpath_table 是一個表函式,它對一組文件中的每個文件評估一組 XPath 查詢,並將結果作為表返回。原始文件表的主鍵欄位作為結果的第一列返回,以便結果集可以方便地用於連線。引數在 表 F.38 中進行了描述。

表 F.38. xpath_table 引數

引數 描述
key

“key”欄位的名稱 — 這只是一個用於輸出表第一列的欄位,即它標識了每一輸出行來自的記錄(有關多值的注意事項,請參見下文)。

document

包含 XML 文件的欄位名稱

relation

包含文件的表或檢視的名稱

xpaths

一個或多個 XPath 表示式,用 | 分隔

criteria

WHERE 子句的內容。此項不能省略,因此如果您想處理 relation 中的所有行,請使用 true1=1


這些引數(XPath 字串除外)將被直接替換到純 SQL SELECT 語句中,因此您具有一定的靈活性 — 語句是:

SELECT <key>, <document> FROM <relation> WHERE <criteria>

因此,這些引數可以是那些特定位置的任何有效內容。此 SELECT 的結果需要返回恰好兩列(除非您嘗試為 key 或 document 列出多個欄位,否則它會返回兩列)。請注意,這種簡單的方法要求您驗證任何使用者提供的輸入值,以避免 SQL 注入攻擊。

該函式必須在 FROM 表示式中使用,並帶有 AS 子句來指定輸出列;例如:

SELECT * FROM
xpath_table('article_id',
            'article_xml',
            'articles',
            '/article/author|/article/pages|/article/title',
            'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);

AS 子句定義了輸出表中列的名稱和型別。第一列是“key”欄位,其餘列對應於 XPath 查詢。如果 XPath 查詢的數量多於結果列的數量,則多餘的查詢將被忽略。如果結果列的數量多於 XPath 查詢的數量,則多餘的列將為 NULL。

請注意,此示例將 page_count 結果列定義為整數。該函式內部處理字串表示形式,因此當您要求輸出為整數時,它將獲取 XPath 結果的字串表示形式,並使用 PostgreSQL 的輸入函式將其轉換為整數(或 text 作為列型別。

呼叫 SELECT 語句不一定只能是 SELECT * — 它可以按名稱引用輸出列,或將其與其他表連線。該函式會生成一個虛擬表,您可以使用該表執行任何所需的操作(例如,聚合、連線、排序等)。因此,我們也可以有

SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
                 '/article/title|/article/author/@id',
                 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
       AS t(article_id integer, title text, author_id integer),
     tblPeopleInfo AS p
WHERE t.author_id = p.person_id;

作為一個更復雜的例子。當然,您可以為了方便起見,將所有這些內容包裝在一個檢視中。

F.50.3.1. 多值結果 #

函式 xpath_table 假定每個 XPath 查詢的結果可能是多值的,因此該函式返回的行數可能與輸入文件的數量不同。返回的第一行包含每個查詢的第一個結果,第二行包含每個查詢的第二個結果。如果某個查詢的值少於其他查詢,則將返回 NULL 值。

在某些情況下,使用者會知道給定的 XPath 查詢只會返回一個結果(可能是唯一的文件識別符號)— 如果與返回多個結果的 XPath 查詢一起使用,該單值結果將僅出現在結果的第一行。解決方法是使用 key 欄位作為連線的一部分,與更簡單的 XPath 查詢進行連線。例如:

CREATE TABLE test (
    id int PRIMARY KEY,
    xml text
);

INSERT INTO test VALUES (1, '<doc num="C1">
<line num="L1"><a>1</a><b>2</b><c>3</c></line>
<line num="L2"><a>11</a><b>22</b><c>33</c></line>
</doc>');

INSERT INTO test VALUES (2, '<doc num="C2">
<line num="L1"><a>111</a><b>222</b><c>333</c></line>
<line num="L2"><a>111</a><b>222</b><c>333</c></line>
</doc>');

SELECT * FROM
  xpath_table('id','xml','test',
              '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
  AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
WHERE id = 1 ORDER BY doc_num, line_num

 id | doc_num | line_num | val1 | val2 | val3
----+---------+----------+------+------+------
  1 | C1      | L1       |    1 |    2 |    3
  1 |         | L2       |   11 |   22 |   33

為了在每一行上都獲取 doc_num,解決方案是兩次呼叫 xpath_table 並連線結果:

SELECT t.*,i.doc_num FROM
  xpath_table('id', 'xml', 'test',
              '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
              'true')
    AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
  xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
    AS i(id int, doc_num varchar(10))
WHERE i.id=t.id AND i.id=1
ORDER BY doc_num, line_num;

 id | line_num | val1 | val2 | val3 | doc_num
----+----------+------+------+------+---------
  1 | L1       |    1 |    2 |    3 | C1
  1 | L2       |   11 |   22 |   33 | C1
(2 rows)

F.50.4. XSLT 函式 #

如果安裝了 libxslt,將提供以下函式:

F.50.4.1. xslt_process #

xslt_process(text document, text stylesheet, text paramlist) returns text

此函式將 XSL 樣式表應用於文件並返回轉換後的結果。paramlist 是要在轉換中使用的一組引數賦值,其格式為 a=1,b=2。請注意,引數解析非常簡單:引數值不能包含逗號!

還有一個兩引數版本的 xslt_process,它不向轉換傳遞任何引數。

F.50.5. 作者 #

John Gray

本模組的開發由 Torchbox Ltd. (www.torchbox.com) 贊助。它與 PostgreSQL 具有相同的 BSD 許可證。

提交更正

如果您在文件中發現任何不正確之處、與您在使用特定功能時的經驗不符之處或需要進一步澄清之處,請使用 此表單 報告文件問題。