9ib XML
9ib XML
9ib XML
XML Enhancements 1- 1
Objectives
XML Enhancements 1- 2
Overview
Reference
Note: For more information on these topics please refer to
• Oracle9i XML Users guide
• Oracle9i Intermedia module
• Oracle9i Business Intelligence Module
XML Enhancements 1- 3
What are the Oracle9i XDK Components?
XML Enhancements 1- 4
XML Standards-Based Technologies
XML Enhancements 1- 5
XML Developer’s Kit Components
XML Enhancements 1- 6
XML Schema Processors
XML Enhancements 1- 7
Oracle9i XDK for Java Beans
• Set of XML visual and non-visual JavaBeans for
building XML-enabled applications
• XDK includes the Transviewer Beans from Oracle8i
• New in Oracle9i: DBAccess Bean and DBView Bean
• DBAccess Bean supports reading and writing XML
to the database
– Supports storing XML documents in XML CLOB
tables
– Supports submitting SQL queries and storing
the results in XML in CLOB tables
• XML DBView Bean provides a control panel for both
database and file XML operations
XML Enhancements 1- 8
XML DBView Bean
XML Enhancements 1- 9
XML Parsers
XML Parsers
The foundation component of any XML development is the XML parser. The parser provides
programmatic access to XML documents enabling them to be used in many ways within an
application. Oracle’s parsers support the two industry-standard specifications for XML document
access – DOM and SAX.
New for Oracle9i is support for DOM 2.0 and SAX 2.0 interfaces to go along with the 1.0 support
previously provided.
The support for DOM 2.0 includes the 2.0 CORE specification which standardizes many
previously custom interfaces primarily for document creation and adds support for XML
namespaces. Additionally, the optional DOM 2.0 traversal-range specification is supported added
signification document navigation functionality through the addition of Treewalkers, Node
Iterators and Node Filters.
Support is also added for SAX 2.0 which adds namespace support through the addition of new
XMLReader, ContentHandler, and Attributes interfaces.
Beyond the additional interfaces, the C and C++ parsers have been redesigned to improve
performance and decrease memory usage.
Finally, the PL/SQL parser is now built upon the C parser significantly improving performance
and resource usage when run within Oracle9i.
XSL Processors
The eXtensible Stylesheet Language, XSL, is the XML-based technology responsible for
transforming or formatting an input XML document into a different output one or rendered into
virtually any text-based output. Integrated into all of the Oracle XML Parsers are XSL Processors
that perform these transformations.
For Oracle9i the Java Processor supports the W3C XSL Transformations 1.1 specification adding
support for standard extension functions in Java and ECMAScript (Java Script).
For Oracle9i the C and C++ Processors have been redesigned for improved performance and
resource usage.
For Oracle9i the PL/SQL Processor is built upon the C one for improved performance.
XSQL Servlet
The XSQL Servlet is a server component written to assist in producing dynamic XML documents
from one or more SQL queries of data objects. It has built-in capabilities to transform the XML
result via XSL to a custom rendering appropriate to the requesting client. The XSQL Servlet uses
a simple declarative .xsql XML file format as its processing instructions. Not only does it support
retrieving data but inserting, updating, and deleting data as well.
It is now possible in Oracle9i to include one or more XSQL parameter references in the value of
the href attribute for an <?xml-stylesheet?> processing instruction. This allows the uri (uniform
resource indicator) for the XSLT stylesheet to be determined dynamically at runtime. The
parameter value may be passed in from the client, as can any parameter value, or assigned to a
page-private parameter whose value is set at runtime using the <xsql:set-page-param> action.
Previously, users relied on <xsql:dml> to accomplish table updates. This release of XSQL adds a
new action handler called <xsql:update-request> which offers a new, declarative option. It offers
the parallel update functionality to complement the declarative insert functionality provided
already with <xsql:insert-request>. The <xsql:update-request> works identically to the
<xsql:insert-request>, in that the posted XML document (optionally transformed by an indicated
XSLT stylesheet) will be processed by the underlying XML SQL Utility.
<?xml
<?xml version="1.0"?>
version="1.0"?>
<?xml-stylesheet
<?xml-stylesheet type="text/xsl"
type="text/xsl" media="MSIE
media="MSIE 5"
5"
href="doyouxml-msie.xsl" ?>
href="doyouxml-msie.xsl" ?>
<?xml-stylesheet
<?xml-stylesheet type="text/xsl"
type="text/xsl" media="Mozilla/3.0“
media="Mozilla/3.0“
href="doyouxml-hw.xsl"
href="doyouxml-hw.xsl" ?>
?>
<?xml-stylesheet
<?xml-stylesheet type="text/xsl"
type="text/xsl" media="Lynx"
media="Lynx"
href="doyouxml-lynx.xsl" ?>
href="doyouxml-lynx.xsl" ?>
<?xml-stylesheet
<?xml-stylesheet type="text/xsl"
type="text/xsl"
href="doyouxml.xsl"
href="doyouxml.xsl" ?>
?>
<query
<query connection="xmldemo">
connection="xmldemo">
select
select value(c)
value(c) as
as Claim
Claim from
from insurance_claim_view
insurance_claim_view cc
where
where c.claimpolicy.primaryinsured.lastname
c.claimpolicy.primaryinsured.lastname == 'Doe'
'Doe'
</query>
</query>
XML Enhancements 2- 1
Objectives
XML Enhancements 2- 2
What are the new Database XML features?
XML Enhancements 2- 3
XMLType
CREATE
CREATE TABLE
TABLE warehouses(
warehouses(
warehouse_id
warehouse_id NUMBER(3),
NUMBER(3),
warehouse_spec
warehouse_spec SYS.XMLTYPE,
SYS.XMLTYPE,
warehouse_name
warehouse_name VARCHAR2(35),
VARCHAR2(35),
location_id
location_id NUMBER(4));
NUMBER(4));
XMLType
Oracle9i has a new native XMLType for storing XML content. This new type is similar
to the other new types that have appeared in the Oracle server over versions 8.0 and 8i.
XMLType gives developers a convenient abstraction to store XML content. There are a
number of built-in member functions on this type that enable developers to manipulate
XML content. Today, the data stored in an XMLType is stored as a character LOB
(CLOB).
XML Enhancements 2- 4
XMLType
XML Enhancements 2- 5
Using XMLType
Using XMLType
The big benefit of a native XMLType is seamless operation with SQL and the rest of the
database platform.
You first define a column of XMLType. You can specify optional storage characteristics
along with the definition.
Use the XMLType constructor to create the XMLType instance before inserting into the
columns. You can also use the SYS_XMLGEN and SYS_XMLAGG operators (we will
look at these later, too), to directly create instances of XMLType.
You can select the XMLType instance from the column. The XMLType offers a choice
of functions and operators, extract() and existsNode() which extract a
particular Node or check to see if a particular node exists in the XMLType, respectively.
You can also create a text index on the XMLType column. We will look at indexing
later.
You can insert and delete from tables using the operators above. Updates are currently
only supported at the document level. You cannot update only part of an XML
document. In order to update part of a document, you have to update the entire
document.
XML Enhancements 2- 6
Example of Using XMLType
CREATE
CREATE TABLE
TABLE warehouses(
warehouses(
warehouse_id
warehouse_id NUMBER(3),
NUMBER(3),
warehouse_spec
warehouse_spec SYS.XMLTYPE,
SYS.XMLTYPE,
warehouse_name
warehouse_name VARCHAR2(35),
VARCHAR2(35),
location_id
location_id NUMBER(4));
NUMBER(4));
INSERT
INSERT INTO
INTO warehouses
warehouses
VALUES
VALUES (5,
(5,
sys.xmltype.createxml('<?xml
sys.xmltype.createxml('<?xml version="1.0"?>
version="1.0"?>
<Warehouse>
<Warehouse>
<Building>Owned</Building>
<Building>Owned</Building>
<Area>25000</Area>
<Area>25000</Area>
<Docks>2</Docks>
<Docks>2</Docks>
<DockType>Rear
<DockType>Rear load</DockType>
load</DockType>
<WaterAccess>Y</WaterAccess>
<WaterAccess>Y</WaterAccess>
<RailAccess>N</RailAccess>
<RailAccess>N</RailAccess>
<Parking>Street</Parking>
<Parking>Street</Parking>
<VClearance>10
<VClearance>10 ft</VClearance>
ft</VClearance>
</Warehouse>'),
</Warehouse>'),
'Toronto',1800);
'Toronto',1800);
XML Enhancements 2- 7
XMLType Storage Characteristics
CREATE
CREATE TABLE
TABLE warehouses(
warehouses(
warehouse_id
warehouse_id NUMBER(3),
NUMBER(3),
warehouse_spec
warehouse_spec SYS.XMLTYPE,
SYS.XMLTYPE,
warehouse_name
warehouse_name VARCHAR2(35),
VARCHAR2(35),
location_id
location_id NUMBER(4))
NUMBER(4))
XMLType
XMLType COLUMN
COLUMN warehouse_spec
warehouse_spec
STORE
STORE AS
AS CLOB
CLOB
(TABLESPACE
(TABLESPACE lob_seg_ts
lob_seg_ts
STORAGE
STORAGE (INITIAL
(INITIAL 4096
4096 NEXT
NEXT 4096)
4096)
CHUNK
CHUNK 4096
4096 NOCACHE
NOCACHE LOGGING);
LOGGING);
XML Enhancements 2- 8
XMLType Functions
XMLType Functions
isFragment() – A fragment might be present if an extract or other operation was
done on a document that resulted in many nodes.
getNumVal() – the call works only if the target node really contains a number.
ExistsNode() – note that the XPath expression must point to a single node, or
multiple nodes, or text values. If it returns a boolean expression, then the
getStringVal returns the literal ‘true’or ‘false’as applicable.
XML Enhancements 2- 9
Example of Using XMLType
SELECT
SELECT w.warehouse_spec.extract
w.warehouse_spec.extract
('/Warehouse/Building/text()').getStringVal()
('/Warehouse/Building/text()').getStringVal()
"Building"
"Building"
FROM
FROM warehouses
warehouses ww
Building
Building
-----------------
-----------------
Owned
Owned
CREATE
CREATE INDEX
INDEX wh_idx
wh_idx ON
ON warehouses
warehouses
(warehouse_spec.extract
(warehouse_spec.extract
('/Warehouse/Building').getStringVal());
('/Warehouse/Building').getStringVal());
• Indexes can be created on the stored CLOB content
CREATE
CREATE INDEX
INDEX wh_spec_idx
wh_spec_idx ON
ON
warehouses((warehouse_spec).getStringVal());
warehouses((warehouse_spec).getStringVal());
Indexing XMLTypes
The above index will help any query like:
SELECT * FROM warehouses
w WHERE
w.warehouse_spec.extract('/Warehouse/Building'). getStringV
al() LIKE 'Owned';
If you want to speed up a query like:
SELECT * FROM warehouses
WHERE warehouse_spec.existsNode('/Warehouse/Area') = 1
then you have to build a functional index on existsNode:
CREATE INDEX wh_idx2 ON
warehouses(warehouse_spec.existsNode('/Warehouse/Area'));
The text index support XPath expressions in Oracle9i. This allows the full-text search
capabilities to be integrated with XML.
SELECT
SELECT ** FROM
FROM warehouse
warehouse ww
WHERE
WHERE w.warehouse_spec.extract
w.warehouse_spec.extract
('/Warehouse/Building').getStringVal()
('/Warehouse/Building').getStringVal()
LIKE
LIKE 'Owned';
'Owned';
DBMS_XMLGEN
Fetch Interface: for example, the first fetch can retrieve a maximum of 10 rows, after
skipping the first two rows.
DBMS_XMLGEN Example
Here is the calling sequence for DBMS_XMLGEN:
Get the context from the package by supplying a SQL query and calling
newContext().
1. Pass the context to all the procedures/functions. For example, you can set the ROW
element’s name using the setRowTag(ctx) call.
2. The XML is generated by calling getXML. By setting the maximum number of
rows to be retrieved per fetch using the setMaxRows() call, you can invoke this
function repeatedly, getting the maximum no. of rows set per call.
3. You can reset the query to start step 2 again.
<?xml
<?xml version=''1.0''?>
version=''1.0''?>
<ROWSET>
<ROWSET>
<EMPLOYEE>
<EMPLOYEE>
<EMPLOYEE_ID>30</EMPLOYEE_ID>
<EMPLOYEE_ID>30</EMPLOYEE_ID>
<LAST_NAME>SCOTT</LAST_NAME>
<LAST_NAME>SCOTT</LAST_NAME>
<SALARY>20000<SALARY>
<SALARY>20000<SALARY>
</EMPLOYEE>
</EMPLOYEE>
<EMPLOYEE>
<EMPLOYEE>
<EMPLOYEE_ID>31</EMPLOYEE_ID>
<EMPLOYEE_ID>31</EMPLOYEE_ID>
<LAST_NAME>MARY</LAST_NAME>
<LAST_NAME>MARY</LAST_NAME>
<AGE>25</AGE>
<AGE>25</AGE>
</EMPLOYEE>
</EMPLOYEE>
</ROWSET>
</ROWSET>
Note: You can also change the tag associated with ROWSET by calling setRowsetTag.
qryCtx
qryCtx :=
:= dbms_xmlgen.newContext
dbms_xmlgen.newContext
('SELECT
('SELECT dept_t(department_id,
dept_t(department_id, department_name,
department_name,
CAST(MULTISET
CAST(MULTISET
(SELECT
(SELECT e.employee_id,
e.employee_id, e.last_name
e.last_name
FROM
FROM employees
employees ee
WHERE
WHERE e.department_id
e.department_id == d.department_id)
d.department_id)
AS
AS emplist_t))
emplist_t))
AS
AS deptxml
deptxml
FROM
FROM departments
departments d');
d');
DBMS_XMLGEN.setRowTag(qryCtx,
DBMS_XMLGEN.setRowTag(qryCtx, NULL);
NULL);
<ROWSET>
<ROWSET>
<DEPTXML
<DEPTXML DEPARTMENT_ID="10">
DEPARTMENT_ID="10">
<DEPARTMENT_NAME>SALES</DEPARTMENT_NAME>
<DEPARTMENT_NAME>SALES</DEPARTMENT_NAME>
<EMPLIST>
<EMPLIST>
<EMP_T
<EMP_T EMPLOYEE_ID="30">
EMPLOYEE_ID="30">
<LAST_NAME>Scott</LAST_NAME>
<LAST_NAME>Scott</LAST_NAME>
</EMP_T>
</EMP_T>
<EMP_T
<EMP_T EMPLOYEE_ID="31">
EMPLOYEE_ID="31">
<LAST_NAME>Mary</LAST_NAME>
<LAST_NAME>Mary</LAST_NAME>
</EMP_T>
</EMP_T>
</EMPLIST>
</EMPLIST>
</DEPTXML>
</DEPTXML>
<DEPTXML
<DEPTXML DEPARTMENT_ID="20">
DEPARTMENT_ID="20">
...
...
</ROWSET>
</ROWSET>
SYS_XMLGEN
DBMS_XMLGEN and other packages operate at a Query level, giving out aggregated
results for an entire query. SYS_XMLGEN, on the other hand, can take a single argument
within a SQL query and convert it to XML.
SYS_XMLGEN works inside SQL queries and operates on expressions and columns
within the row. DBMS_XMLGEN works on the entire resultset.
SYS_XMLAGG
Here, we are aggregating data together pretty much as in a GROUP BY operation, with
the GROUP BY also showing up on the XML document produced.
SYS_XMLAGG also works with OLAP aggregation functionality such as ROLLUP and
CUBE. You can thus create different XML documents based on ROLLUP and CUBE
operations.
Oracle provides windowing functions that can be used to compute cumulative, moving
and centered aggregates. SYS_XMLAGG can be used with these as well, to create
documents based on rank and partition.
<EmployeeGroup>
<EmployeeGroup>
<last_name>Scott</last_name>
<last_name>Scott</last_name>
<last_name>Mary<last_name>
<last_name>Mary<last_name>
</EmployeeGroup
</EmployeeGroup >>
<EmployeeGroup
<EmployeeGroup >>
<last_name>Jack</last_name>
<last_name>Jack</last_name>
<last_name>John>/last_name>
<last_name>John>/last_name>
</EmployeeGroup
</EmployeeGroup >>
TABLE Functions
A TABLE function can be used to take an external purchase order document and, using
the ODCITable interface, convert it into a set of SQL rows. The server can perform this
conversion with high efficiency. The SQL rows can then be stored in regular tables. The
mapping between the external XML document and the database table then helps in the
definition of the table function.
Reference
Note: Please refer the Extensibility module and SQL/PLSQL module for more
information on table functions.
Database URI-References
Another DBURI-Ref example:
employees table has a column called address, which contains state, city, street and zip attributes
/SCOTT/EMPLOYEES/ROW[ADDRESS/STATE='CA' OR
STATE='OR']/ADDRESS[CITY='PORTLAND' OR ./ZIPCODE =94404]/CITY
The above DBURI-Ref identifies the city attribute of the address column in the employees table in
scott’s schema whose state is either California or Oregon or the city name is Portland or the zip code is
94404.
DBURI-Ref is a simplified XPath format. For this release Oracle does not support the full flavor of
XPath or XPointer for a DBURI-Ref.
SQL>
SQL> CREATE
CREATE TABLE
TABLE tax_deductible_tab
tax_deductible_tab ((
22 uri_col
uri_col UriType,
UriType,
33 max_deduction
max_deduction NUMBER(7,2),
NUMBER(7,2),
44 description
description VARCHAR2);
VARCHAR2);
SQL>
SQL> INSERT
INSERT INTO
INTO tax_deductible_tab
tax_deductible_tab VALUES
VALUES ((
22 UriFactory.getURL
UriFactory.getURL
33 ('/SCOTT/Warehouses/ROW[Area=2500'),
('/SCOTT/Warehouses/ROW[Area=2500'),
44 2500.00,
2500.00, 'Scott''s
'Scott''s Warehouse
Warehouse Info');
Info');
SQL>
SQL> INSERT
INSERT INTO
INTO tax_deductible_tab
tax_deductible_tab VALUES
VALUES ((
22 UriFactory.getURL
UriFactory.getURL
33 ('http://proxy.oracle.com/webaccts/pos/scott/po1'),
('http://proxy.oracle.com/webaccts/pos/scott/po1'),
44 1000.00,
1000.00, 'Scott''s
'Scott''s Web
Web PO');
PO');
Using URITypes
The UriFactory package contains methods to generate the appropriate kind of URI
without having to hard code the implementation in the program
The factory method can take strings representing the various URLs and return the
appropriate subtype instance.
For example, if the prefix starts with a http://, it creates a HTTPUriType and returns a
reference to that instance, after stripping out the http:// prefix. If the string starts with a
/oradb/ or similar prefix, it returns a DBUriType instance.
The factory also provides the ability to register new subtypes of the URiType to handle
other protocols not supported by Oracle9i. If you wish, you can invent a new protocol
b2b://, create a subtype of UriType to handle that protocol and register this protocol with
the UriFactory. The factory can then generate instance of your subtype whenever it saw
a URI with the b2b:// prefix.
SELECT
SELECT e.ur_col.getClob()
e.ur_col.getClob()
FROM
FROM tax_deductible_tab
tax_deductible_tab e;
e;
--PL/SQL
--PL/SQL
DECLARE
DECLARE
V_uri
V_uri UriType;
UriType;
BEGIN
BEGIN
SELECT
SELECT uri_col
uri_col into
into v_uri
v_uri
FROM
FROM tax_deductible_tab
tax_deductible_tab
WHERE
WHERE Description
Description LIKE
LIKE 'Scott%';
'Scott%';
printDataOut(v_uri.getClob());
printDataOut(v_uri.getClob());
END;
END;
URIType Methods
getClob: The character set of the encoding will be the database character set.
getURL: URIType has a hidden attribute called URL. Do not use this directly; use
getURL instead.
getExternalURL: For example, spaces are converted to the escaped value %20.
INSERT
INSERT INTO
INTO doc_list_tab(
doc_list_tab(
1001,
1001,
SELECT
SELECT SYS_DBURIGEN(employee_id,last_name)
SYS_DBURIGEN(employee_id,last_name)
FROM
FROM employees
employees WHERE
WHERE employee_id
employee_id == 7369);
7369);
SYS_DBURIGEN()
DBURIs can be created statically using path expressions in a constructor of the
UriFactory
The result of the SYS_DBURIGEN looks like:
/SCOTT/EMPLOYEES/ROW[employee_id=7369]/last_name