支援的版本:目前版本 (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.48. xml2 — XPath 查詢與 XSLT 功能 #

xml2 模組提供 XPath 查詢與 XSLT 功能。

F.48.1. 已棄用通知 #

PostgreSQL 8.3 開始,核心伺服器中已有基於 SQL/XML 標準的 XML 相關功能。 該功能涵蓋 XML 語法檢查和 XPath 查詢,這也是此模組所做的,而且更多,但 API 完全不相容。 計劃在未來版本的 PostgreSQL 中移除此模組,以支持較新的標準 API,因此建議您嘗試轉換您的應用程式。 如果您發現此模組的某些功能無法透過較新的 API 以足夠的形式提供,請將您的問題說明給 以便能夠解決此缺陷。

F.48.2. 函數描述 #

表 F.35 顯示了此模組提供的函數。 這些函數提供了簡單的 XML 解析和 XPath 查詢。

表 F.35. 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.48.3. xpath_table #

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

xpath_table 是一個表格函式,它會在一組文件上評估一組 XPath 查詢,並將結果以表格形式傳回。 原始文件表格的主鍵欄位會作為結果的第一欄傳回,以便結果集可以輕鬆地用於聯結。 參數描述於表格 F.36

表格 F.36. xpath_table 參數

參數 描述
key(鍵)

key 欄位的名稱 — 這只是一個要用作輸出表格的第一欄的欄位,也就是說,它識別每個輸出列來自哪個記錄(請參閱下面關於多個值的注意事項)

document(文件)

包含 XML 文件的欄位名稱

relation(關係)

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

xpaths

一個或多個 XPath 表達式,以 | 分隔

criteria(條件)

WHERE 子句的內容。 這不能省略,所以如果您想處理關係中的所有列,請使用 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 輸入函式將其轉換為整數(或 AS 子句要求的任何類型)。 如果它無法做到這一點 — 例如,如果結果為空 — 將會產生錯誤,因此如果您認為您的資料有任何問題,您可能希望只堅持使用 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.48.3.1. 多值結果 #

xpath_table 函式假設每個 XPath 查詢的結果可能是多值的,因此該函式傳回的列數可能與輸入文件的數量不同。 傳回的第一列包含每個查詢的第一個結果,第二列包含每個查詢的第二個結果。 如果其中一個查詢的值少於其他查詢,則會傳回空值。

在某些情況下,使用者會知道給定的 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.48.4. XSLT 函式 #

如果安裝了 libxslt,則可以使用以下函式

F.48.4.1. xslt_process #

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

這個函式將 XSL 樣式表應用於文件,並傳回轉換後的結果。 paramlist 是要用於轉換的參數賦值列表,以 a=1,b=2 的形式指定。 請注意,參數解析非常簡單:參數值不能包含逗號!

還有一個雙參數版本的 xslt_process,它不會將任何參數傳遞給轉換。

F.48.5. 作者 #

John Gray

這個模組的開發由 Torchbox Ltd. (www.torchbox.com) 贊助。 它具有與 PostgreSQL 相同的 BSD 授權。

提交更正

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