fn:doc(uri):查詢 **單個** Repository 文件資源 (如 /public/employees/employees.xml)fn:collection(uri):查詢 **同一目錄下多個** 文件資源 (如 /public/employees)先有 employees.xml (來自 HR.EMPLOYEES),再用 PL/SQL 基於 SCOTT.DEPT/EMP 生成 acc_dept.xml 存入同目錄:
DECLARE
xmldoc XMLTYPE;
BEGIN
SELECT XMLQuery(
'for $j in ora:view("SCOTT", "dept")/ROW
where $j/DEPTNO = 10
return
{$j/DEPTNO, $j/DNAME}
{
for $i in ora:view("SCOTT", "emp")/ROW
where $i/DEPTNO = $j/DEPTNO
return {$i/EMPNO, $i/ENAME, $i/SAL}
}
'
RETURNING CONTENT) INTO xmldoc FROM DUAL;
IF DBMS_XDB.CREATERESOURCE('/public/employees/acc_dept.xml', xmldoc) THEN
DBMS_OUTPUT.PUT_LINE('Resource created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/
-- 需以 SCOTT/TIGER 登入執行
兩文件結構不同:
employees.xml:根元素 <EMPLOYEES>acc_dept.xml:根元素 <DEPARTMENT>使用 XPath // (任意深度後代) 忽略結構差異,直接定位 <EMPLOYEE>:
SELECT XMLQuery(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
order by $i/ENAME
return $i'
RETURNING CONTENT) FROM DUAL;
102 De Haan 17000
7839 KING 5000
100 King 24000
101 Kochhar 17000
應用層處理關係數據時,用 XMLTable 將 XML 節點映射為 SQL 虛擬表列:
SELECT emps.empno, emps.ename, emps.sal
FROM XMLTable(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
return $i'
COLUMNS
empno NUMBER PATH '/EMPLOYEE/EMPNO',
ename VARCHAR2(30) PATH '/EMPLOYEE/ENAME',
sal NUMBER PATH '/EMPLOYEE/SAL'
) emps;
EMPNO ENAME SAL
----- ---------- -----
7839 KING 5000
100 King 24000
101 Kochhar 17000
102 De Haan 17000
| 技術 | 用途 | 核心語法 |
|---|---|---|
| fn:doc() | 單文件查詢 | fn:doc('/public/employees/employees.xml') |
| fn:collection() | 目錄級多文件查詢 | fn:collection('/public/employees') |
| XPath // | 跨異構文件統一定位 | //EMPLOYEE |
| XMLTable | XML → 關係虛擬表 | COLUMNS col TYPE PATH 'xpath' |
| ora:view() | 關係表 → XML 視圖 | ora:view("schema", "table")/ROW |
fn:collection 範圍控制xs:string(), xs:integer(), xs:date() 避免隱式轉換錯誤declare namespace ns="...";