Skip to content

Commit ef6a97b

Browse files
Merge pull request #1954 from oracle-devrel/witold-swierzy-patch-10
Witold swierzy patch 10
2 parents 9b3cb84 + b773a2e commit ef6a97b

File tree

20 files changed

+1791
-0
lines changed

20 files changed

+1791
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
This repo contains PL/SQL API for document conversion demonstrating how it is possible to abstract from a particular format (XML or JSON) and work on the data.
2+
3+
- doc directory contains documentation, including overview presentation and user guide
4+
- sql directory contains API code with scripts allowing easy installation and removal
5+
- demo directory contains script demonstrating functionality of the API
6+
7+
# License
8+
9+
Copyright (c) 2025 Oracle and/or its affiliates.
10+
11+
Licensed under the Universal Permissive License (UPL), Version 1.0.
12+
13+
See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details.
14+
15+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
-- this demo demonstrates basic functionality of Document Conversion API
2+
-- requirements: HR sample schema
3+
drop table if exists emp_xml_table;
4+
5+
create table emp_xml_table OF XMLType
6+
as
7+
select XMLElement("Emp",
8+
XMLForest( e.employee_id AS "employee_id",
9+
e.first_name AS "first_name",
10+
e.last_name AS "last_name",
11+
e.hire_date AS "hiredate"))
12+
"result" FROM hr.employees e;
13+
14+
-- alternative
15+
drop table if exists emp_xml_table;
16+
17+
create table emp_xml_table of XMLType
18+
as
19+
select doc_conv.json2xml(JSON{*}) employee
20+
from hr.employees;
21+
--
22+
select * from emp_xml_table;
23+
24+
select doc_conv.xml2json(value(e)) json_col
25+
from emp_xml_table e;
26+
27+
create or replace json collection view emp_json_view
28+
as
29+
select doc_conv.xml2json(value(e)) data
30+
from emp_xml_table e;
31+
32+
select *
33+
from emp_json_view;
34+
35+
mongosh :
36+
db.emp_json_view.find()
37+
db.emp_json_view.find({"SALARY":6200})
38+
db.emp_json_view.find({"SALARY":6200}).explain()
39+
40+
41+
42+
43+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
-- basic document manipulation
2+
-- requirements: HR demo schema
3+
drop table if exists dept_xml_table;
4+
5+
create table dept_xml_table
6+
as
7+
select department_id, doc_conv.json2xml(JSON{*}) department
8+
from hr.departments;
9+
10+
select *
11+
from dept_xml_table;
12+
13+
create or replace json collection view dept_json_view
14+
as
15+
select doc_conv.xml2json(department)
16+
from dept_xml_table;
17+
18+
select *
19+
from dept_json_view;
20+
21+
declare
22+
cursor c_dept is select * from dept_xml_table for update;
23+
de DocElement;
24+
begin
25+
for r_dept in c_dept loop
26+
de := DocElement(r_dept.department);
27+
de.setRootKey('DEPARTMENT');
28+
29+
update dept_xml_table
30+
set department = de.getAsXML
31+
where current of c_dept;
32+
end loop;
33+
commit;
34+
end;
35+
/
36+
37+
select *
38+
from dept_xml_table;
39+
40+
select *
41+
from dept_json_view;
42+
43+
declare
44+
cursor c_dept is select * from dept_xml_table for update;
45+
de DocElement;
46+
begin
47+
for r_dept in c_dept loop
48+
de := DocElement(r_dept.department);
49+
de.delElement('MANAGER_ID');
50+
51+
update dept_xml_table
52+
set department = de.getAsXML
53+
where current of c_dept;
54+
end loop;
55+
commit;
56+
end;
57+
/
58+
59+
select *
60+
from dept_xml_table;
61+
62+
select *
63+
from dept_json_view;
64+
65+
declare
66+
cursor c_dept is select * from dept_xml_table for update;
67+
de DocElement;
68+
nde DocElement;
69+
NofEMPS integer;
70+
begin
71+
for r_dept in c_dept loop
72+
de := DocElement(r_dept.department);
73+
nde := de.getElement('DEPARTMENT_ID');
74+
75+
select count(*)
76+
into NofEMPS
77+
from hr.employees
78+
where department_id = to_char(nde.val);
79+
80+
de.addElement('NO_OF_EMPS',to_clob(NofEMPS));
81+
82+
update dept_xml_table
83+
set department = de.getAsXML
84+
where current of c_dept;
85+
end loop;
86+
commit;
87+
end;
88+
/
89+
90+
select *
91+
from dept_xml_table;
92+
93+
select *
94+
from dept_json_view;
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
-- arrays
2+
-- requires HR sample schema
3+
set serveroutput on
4+
5+
declare
6+
de DocElement := DocElement.getArray('select * from hr.employees '||
7+
'where department_id = 90','EMP_90','EMPLOYEE');
8+
dx XMLType;
9+
dj JSON_ELEMENT_T;
10+
begin
11+
dbms_output.put_line('type : '||de.getElType);
12+
dj := de.getAsJSON;
13+
dx := de.getAsXML;
14+
dbms_output.put_line('------- JSON DATA -------');
15+
dbms_output.put_line(dj.to_String);
16+
dbms_output.put_line('---- END OF JSON DATA ---');
17+
dbms_output.put_line('------- XML DATA --------');
18+
dbms_output.put_line(dx.getClobVal);
19+
dbms_output.put_line('---- END OF XML DATA ----');
20+
end;
21+
/
22+
23+
drop table if exists dept_emp_json_table;
24+
create json collection table dept_emp_json_table;
25+
26+
drop table if exists dept_emp_xml_table;
27+
create table dept_emp_xml_table of XMLType;
28+
29+
declare
30+
dept_emp_de DocElement := DocElement();
31+
dept_de DocElement := DocElement();
32+
emp_de DocElement := DocElement();
33+
dept_id DocElement;
34+
jd JSON_ELEMENT_T;
35+
xd XMLType;
36+
jc clob;
37+
begin
38+
dept_emp_de.setRootKey('DEPARTMENTS');
39+
40+
for rd in (select JSON{*} dept from hr.departments) loop
41+
dept_de := DocElement(JSON_ELEMENT_T.parse(JSON_SERIALIZE(rd.dept)));
42+
dept_de.setRootKey('DEPARTMENT');
43+
dept_id := dept_de.getElement('DEPARTMENT_ID');
44+
emp_de := DocElement.getArray('select * from hr.employees where department_id = '||dept_id.val,'EMPLOYEES','EMP');
45+
46+
if emp_de is not null then
47+
dept_de.addElement(emp_de);
48+
end if;
49+
50+
jd := dept_de.getAsJSON;
51+
xd := dept_de.getAsXML;
52+
jc := jd.to_Clob;
53+
54+
insert into dept_emp_json_table values (jc);
55+
insert into dept_emp_xml_table values (xd);
56+
end loop;
57+
commit;
58+
59+
end;
60+
/
61+
62+
select *
63+
from dept_emp_json_table;
64+
65+
select *
66+
from dept_emp_xml_table;
67+
68+
-- or
69+
70+
declare
71+
dept_de DocElement;
72+
jd JSON_ELEMENT_T;
73+
xd XMLType;
74+
begin
75+
for rd in (select JSON{*} dept from hr.departments) loop
76+
dept_de := DocElement(JSON_ELEMENT_T.parse(JSON_SERIALIZE(rd.dept)));
77+
dept_de.setRootKey('DEPARTMENT');
78+
dept_de.aggregate('HR.EMPLOYEES','DEPARTMENT_ID');
79+
jd := dept_de.getAsJSON;
80+
xd := dept_de.getAsXML;
81+
dbms_output.put_line(jd.to_String);
82+
dbms_output.put_line(xd.getClobVal);
83+
end loop;
84+
end;
85+
/
86+
87+
select xmltojson(XMLType('<a><![CDATA[characters with markup]]><b attrb="valb">aaa</b><b>ccc</b></a>'))
88+
select doc_conv.xml2json(XMLType('<a><b attrb="valb">aaa</b><b>ccc</b></a>'))
89+
select jsontoxml(json{*}) from hr.departments;
90+
select doc_conv.json2xml(json{*}) from hr.departments;
91+
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
-- this demo demonstrates comments and attributes support
2+
-- requirements: HR sample schema
3+
4+
-- 1. Comments
5+
drop table if exists dept_xml_table;
6+
7+
create table dept_xml_table
8+
as
9+
select department_id, doc_conv.json2xml(JSON{*}) department
10+
from hr.departments;
11+
12+
select *
13+
from dept_xml_table;
14+
15+
declare
16+
cursor c_dept is select * from dept_xml_table for update;
17+
de DocElement;
18+
dj JSON_ELEMENT_T;
19+
dx XMLType;
20+
i integer := 0;
21+
begin
22+
for r in c_dept loop
23+
24+
i := i+1;
25+
26+
de := DocElement(r.department);
27+
de.addComment('Comment for department : '||r.department_id);
28+
29+
dx := de.getAsXML;
30+
31+
update dept_xml_table
32+
set department = dx
33+
where current of c_dept;
34+
35+
end loop;
36+
commit;
37+
end;
38+
/
39+
40+
select department
41+
from dept_xml_table;
42+
43+
create or replace json collection view dept_json_view
44+
as
45+
select doc_conv.xml2json(department)
46+
from dept_xml_table;
47+
48+
select *
49+
from dept_json_view;
50+
51+
select doc_conv.json2xml(data)
52+
from dept_json_view;
53+
54+
-- 2.Attributes
55+
declare
56+
cursor c_dept is select * from dept_xml_table for update;
57+
de DocElement;
58+
dj JSON_ELEMENT_T;
59+
dx XMLType;
60+
da DocAttribute;
61+
i integer := 0;
62+
begin
63+
for r in c_dept loop
64+
de := DocElement(r.department);
65+
66+
select count(*)
67+
into i
68+
from hr.employees
69+
where department_id = r.department_id;
70+
71+
da := DocAttribute('no_of_emps',to_clob(i));
72+
dbms_output.put_line('i = '||i);
73+
dbms_output.put_line('key = '||da.key||' val = '||da.val);
74+
75+
de.addAttr(da);
76+
dx := de.getAsXML;
77+
78+
update dept_xml_table
79+
set department = dx
80+
where current of c_dept;
81+
82+
end loop;
83+
commit;
84+
end;
85+
/
86+
87+
select *
88+
from dept_xml_table;
89+
90+
select *
91+
from dept_json_view;
92+
93+
select doc_conv.json2xml(data)
94+
from dept_json_view;
95+
96+
declare
97+
xd XMLType := XMLType('<a attra="val_attr_a"><a1>val_a1</a1><a2>val_a2</a2></a>');
98+
ed DocElement := DocElement(xd);
99+
jd JSON_ELEMENT_T := ed.getAsJSON;
100+
begin
101+
dbms_output.put_line('before attribute to element transformation : ');
102+
dbms_output.put_line(xd.getclobval);
103+
dbms_output.put_line(jd.to_String);
104+
105+
ed.attr2element('attra');
106+
107+
xd := ed.getAsXML;
108+
jd := ed.getAsJSON;
109+
110+
dbms_output.put_line('after attribute to element transformation : ');
111+
dbms_output.put_line(xd.getclobval);
112+
dbms_output.put_line(jd.to_String);
113+
114+
ed.element2attr('a1');
115+
xd := ed.getAsXML;
116+
jd := ed.getAsJSON;
117+
dbms_output.put_line('after element to attribute transformation : ');
118+
dbms_output.put_line(xd.getclobval);
119+
dbms_output.put_line(jd.to_String);
120+
end loop;
121+
/
122+
123+
124+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
create or replace type body DocAttribute as
2+
constructor function DocAttribute(aName clob, avalue clob) return self as result
3+
is
4+
begin
5+
key := aName;
6+
val := aValue;
7+
return;
8+
end;
9+
10+
overriding member function getCompType return integer
11+
is
12+
begin
13+
return doc_utl.comp_attribute;
14+
end;
15+
16+
overriding member function toString(fmt integer) return clob
17+
is
18+
begin
19+
if fmt = doc_utl.fmt_xml then
20+
return key||'="'||val||'"';
21+
elsif fmt = doc_utl.fmt_json then
22+
return '"'||key||'":"'||val||'"';
23+
end if;
24+
end;
25+
end;
26+
/

0 commit comments

Comments
 (0)