Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
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.

- doc directory contains documentation, including overview presentation and user guide
- sql directory contains API code with scripts allowing easy installation and removal
- demo directory contains script demonstrating functionality of the API

# License

Copyright (c) 2025 Oracle and/or its affiliates.

Licensed under the Universal Permissive License (UPL), Version 1.0.

See [LICENSE](https://github.com/oracle-devrel/technology-engineering/blob/main/LICENSE) for more details.


Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
-- this demo demonstrates basic functionality of Document Conversion API
-- requirements: HR sample schema
drop table if exists emp_xml_table;

create table emp_xml_table OF XMLType
as
select XMLElement("Emp",
XMLForest( e.employee_id AS "employee_id",
e.first_name AS "first_name",
e.last_name AS "last_name",
e.hire_date AS "hiredate"))
"result" FROM hr.employees e;

-- alternative
drop table if exists emp_xml_table;

create table emp_xml_table of XMLType
as
select doc_conv.json2xml(JSON{*}) employee
from hr.employees;
--
select * from emp_xml_table;

select doc_conv.xml2json(value(e)) json_col
from emp_xml_table e;

create or replace json collection view emp_json_view
as
select doc_conv.xml2json(value(e)) data
from emp_xml_table e;

select *
from emp_json_view;

mongosh :
db.emp_json_view.find()
db.emp_json_view.find({"SALARY":6200})
db.emp_json_view.find({"SALARY":6200}).explain()





Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
-- basic document manipulation
-- requirements: HR demo schema
drop table if exists dept_xml_table;

create table dept_xml_table
as
select department_id, doc_conv.json2xml(JSON{*}) department
from hr.departments;

select *
from dept_xml_table;

create or replace json collection view dept_json_view
as
select doc_conv.xml2json(department)
from dept_xml_table;

select *
from dept_json_view;

declare
cursor c_dept is select * from dept_xml_table for update;
de DocElement;
begin
for r_dept in c_dept loop
de := DocElement(r_dept.department);
de.setRootKey('DEPARTMENT');

update dept_xml_table
set department = de.getAsXML
where current of c_dept;
end loop;
commit;
end;
/

select *
from dept_xml_table;

select *
from dept_json_view;

declare
cursor c_dept is select * from dept_xml_table for update;
de DocElement;
begin
for r_dept in c_dept loop
de := DocElement(r_dept.department);
de.delElement('MANAGER_ID');

update dept_xml_table
set department = de.getAsXML
where current of c_dept;
end loop;
commit;
end;
/

select *
from dept_xml_table;

select *
from dept_json_view;

declare
cursor c_dept is select * from dept_xml_table for update;
de DocElement;
nde DocElement;
NofEMPS integer;
begin
for r_dept in c_dept loop
de := DocElement(r_dept.department);
nde := de.getElement('DEPARTMENT_ID');

select count(*)
into NofEMPS
from hr.employees
where department_id = to_char(nde.val);

de.addElement('NO_OF_EMPS',to_clob(NofEMPS));

update dept_xml_table
set department = de.getAsXML
where current of c_dept;
end loop;
commit;
end;
/

select *
from dept_xml_table;

select *
from dept_json_view;
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
-- arrays
-- requires HR sample schema
set serveroutput on

declare
de DocElement := DocElement.getArray('select * from hr.employees '||
'where department_id = 90','EMP_90','EMPLOYEE');
dx XMLType;
dj JSON_ELEMENT_T;
begin
dbms_output.put_line('type : '||de.getElType);
dj := de.getAsJSON;
dx := de.getAsXML;
dbms_output.put_line('------- JSON DATA -------');
dbms_output.put_line(dj.to_String);
dbms_output.put_line('---- END OF JSON DATA ---');
dbms_output.put_line('------- XML DATA --------');
dbms_output.put_line(dx.getClobVal);
dbms_output.put_line('---- END OF XML DATA ----');
end;
/

drop table if exists dept_emp_json_table;
create json collection table dept_emp_json_table;

drop table if exists dept_emp_xml_table;
create table dept_emp_xml_table of XMLType;

declare
dept_emp_de DocElement := DocElement();
dept_de DocElement := DocElement();
emp_de DocElement := DocElement();
dept_id DocElement;
jd JSON_ELEMENT_T;
xd XMLType;
jc clob;
begin
dept_emp_de.setRootKey('DEPARTMENTS');

for rd in (select JSON{*} dept from hr.departments) loop
dept_de := DocElement(JSON_ELEMENT_T.parse(JSON_SERIALIZE(rd.dept)));
dept_de.setRootKey('DEPARTMENT');
dept_id := dept_de.getElement('DEPARTMENT_ID');
emp_de := DocElement.getArray('select * from hr.employees where department_id = '||dept_id.val,'EMPLOYEES','EMP');

if emp_de is not null then
dept_de.addElement(emp_de);
end if;

jd := dept_de.getAsJSON;
xd := dept_de.getAsXML;
jc := jd.to_Clob;

insert into dept_emp_json_table values (jc);
insert into dept_emp_xml_table values (xd);
end loop;
commit;

end;
/

select *
from dept_emp_json_table;

select *
from dept_emp_xml_table;

-- or

declare
dept_de DocElement;
jd JSON_ELEMENT_T;
xd XMLType;
begin
for rd in (select JSON{*} dept from hr.departments) loop
dept_de := DocElement(JSON_ELEMENT_T.parse(JSON_SERIALIZE(rd.dept)));
dept_de.setRootKey('DEPARTMENT');
dept_de.aggregate('HR.EMPLOYEES','DEPARTMENT_ID');
jd := dept_de.getAsJSON;
xd := dept_de.getAsXML;
dbms_output.put_line(jd.to_String);
dbms_output.put_line(xd.getClobVal);
end loop;
end;
/

select xmltojson(XMLType('<a><![CDATA[characters with markup]]><b attrb="valb">aaa</b><b>ccc</b></a>'))
select doc_conv.xml2json(XMLType('<a><b attrb="valb">aaa</b><b>ccc</b></a>'))
select jsontoxml(json{*}) from hr.departments;
select doc_conv.json2xml(json{*}) from hr.departments;

Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
-- this demo demonstrates comments and attributes support
-- requirements: HR sample schema

-- 1. Comments
drop table if exists dept_xml_table;

create table dept_xml_table
as
select department_id, doc_conv.json2xml(JSON{*}) department
from hr.departments;

select *
from dept_xml_table;

declare
cursor c_dept is select * from dept_xml_table for update;
de DocElement;
dj JSON_ELEMENT_T;
dx XMLType;
i integer := 0;
begin
for r in c_dept loop

i := i+1;

de := DocElement(r.department);
de.addComment('Comment for department : '||r.department_id);

dx := de.getAsXML;

update dept_xml_table
set department = dx
where current of c_dept;

end loop;
commit;
end;
/

select department
from dept_xml_table;

create or replace json collection view dept_json_view
as
select doc_conv.xml2json(department)
from dept_xml_table;

select *
from dept_json_view;

select doc_conv.json2xml(data)
from dept_json_view;

-- 2.Attributes
declare
cursor c_dept is select * from dept_xml_table for update;
de DocElement;
dj JSON_ELEMENT_T;
dx XMLType;
da DocAttribute;
i integer := 0;
begin
for r in c_dept loop
de := DocElement(r.department);

select count(*)
into i
from hr.employees
where department_id = r.department_id;

da := DocAttribute('no_of_emps',to_clob(i));
dbms_output.put_line('i = '||i);
dbms_output.put_line('key = '||da.key||' val = '||da.val);

de.addAttr(da);
dx := de.getAsXML;

update dept_xml_table
set department = dx
where current of c_dept;

end loop;
commit;
end;
/

select *
from dept_xml_table;

select *
from dept_json_view;

select doc_conv.json2xml(data)
from dept_json_view;

declare
xd XMLType := XMLType('<a attra="val_attr_a"><a1>val_a1</a1><a2>val_a2</a2></a>');
ed DocElement := DocElement(xd);
jd JSON_ELEMENT_T := ed.getAsJSON;
begin
dbms_output.put_line('before attribute to element transformation : ');
dbms_output.put_line(xd.getclobval);
dbms_output.put_line(jd.to_String);

ed.attr2element('attra');

xd := ed.getAsXML;
jd := ed.getAsJSON;

dbms_output.put_line('after attribute to element transformation : ');
dbms_output.put_line(xd.getclobval);
dbms_output.put_line(jd.to_String);

ed.element2attr('a1');
xd := ed.getAsXML;
jd := ed.getAsJSON;
dbms_output.put_line('after element to attribute transformation : ');
dbms_output.put_line(xd.getclobval);
dbms_output.put_line(jd.to_String);
end loop;
/



Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
create or replace type body DocAttribute as
constructor function DocAttribute(aName clob, avalue clob) return self as result
is
begin
key := aName;
val := aValue;
return;
end;

overriding member function getCompType return integer
is
begin
return doc_utl.comp_attribute;
end;

overriding member function toString(fmt integer) return clob
is
begin
if fmt = doc_utl.fmt_xml then
return key||'="'||val||'"';
elsif fmt = doc_utl.fmt_json then
return '"'||key||'":"'||val||'"';
end if;
end;
end;
/
Loading