Skip Headers

Oracle9i XML Database Developer's Guide - Oracle XML DB
Release 2 (9.2)

Part Number A96620-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Feedback

Go to previous page Go to next page
View PDF

3
Using Oracle XML DB

This chapter describes where and how you can use Oracle XML DB. It discusses and includes examples on common Oracle XML DB usage scenarios including XMLType data storage and access, updating and validating your data, and why it helps to understand XPath and XML Schema. It provides you with ideas for how you can use the Repository to store, access, and manipulate database data using standard protocols from a variety of clients.

The chapter also discusses how you can define a default XML table for storing XML schema-based documents and using XDBUriType to access non-schema-based content.

It contains the following sections:

Storing Data in an XMLType Column or XMLType Table

When storing XML documents in Oracle9i database you can use a number of approaches, including:

Example 3-1 Creating a Table with an XMLType Column

CREATE TABLE Example1
(
    KEYVALUE  varchar2(10)  primary key,
    XMLCOLUMN xmltype
);   

Example 3-2 Creating a Table of XMLType

CREATE TABLE XMLTABLE OF XMLType;

Example 3-3 Storing an XML Document by First Creating an XMLType Instance Using getDocument()

To store an XML document in an XMLType table or column the XML document must first be converted into an XMLType instance. This is done using the different constructors provided by the XMLType datatype. For example, given a PL/SQL function called getCLOBDocument():

create or replace function getClobDocument(
filename in varchar2,
 charset in varchar2 default NULL)
 return CLOB deterministic
 is
    file            bfile := bfilename('DIR',filename);
    charContent     CLOB := ' ';
    targetFile      bfile;
    lang_ctx        number := DBMS_LOB.default_lang_ctx;
    charset_id      number := 0;
    src_offset      number := 1 ;
    dst_offset      number := 1 ;
    warning         number;
 begin
   if charset is not null then
       charset_id := NLS_CHARSET_ID(charset);
   end if;
   targetFile := file;
   DBMS_LOB.fileopen(targetFile, DBMS_LOB.file_readonly);
   DBMS_LOB.LOADCLOBFROMFILE(charContent, targetFile,
           DBMS_LOB.getLength(targetFile), src_offset, dst_offset,
           charset_id, lang_ctx,warning);
   DBMS_LOB.fileclose(targetFile);
   return charContent;
 end;
 /
-- create XMLDIR directory
-- connect system/manager
-- create directory XMLDIR as '<location_of_xmlfiles_on_server>';
-- grant read on directory xmldir to public with grant option;

-- you can use getCLOBDocument() to generate a CLOB from a file containin
-- an XML document. For example, the following statement inserts a row into the 
-- XMLType table Example2 created earlier:

INSERT INTO XMLTABLE 
VALUES(XMLTYPE(getCLOBDocument('purchaseorder.xml')));

Note the use of parameter, "charset". This is used to identify the character set of the designated file. If omitted, the default character set id of the current database is used.

For example, if a file, invoice.xml uses one of the Korean character sets, KO16KSC5601, it can be loaded into XMLType table, XMLDOC as follows:

insert into xmldoc
   values(xmltype(getClobDocument('invoice.xml','KO16KSC5601')));

The following example uses the UTF8 file format:

insert into xmldoc
   values(xmltype(getClobDocument('invoice.xml','UTF8')));

In the last example both the database and the file use the same character set such as UTF8:

insert into xmldoc values(xmltype(getClobDocument('invoice.xml')));

Note:

Oracle XML DB can handle multibyte characters as long as the client character set is the same as the database character set.


Accessing Data in XMLType Columns or XMLType Tables

Once a collection of XML documents have been stored as XMLType tables or columns the next step is to be able to retrieve them. When working with a collection of XML documents you have two fundamental tasks to perform:

Oracle9i database and XMLType datatype provide a number of functions that make it easy to perform these tasks. These functions make use of the W3C XPath recommendation to navigate across and within a collection of XML documents.

See Also:

Appendix C, "XPath and Namespace Primer" for an introduction to the W3C XPath Recommendation.

Using XPath with Oracle XML DB

A number of the functions provided by the Oracle XML DB are based on the W3C XPath recommendation. XPath traverses nested XML elements by your specifying the elements to navigate through with a slash-separated list of element and attribute names. By using XPath to define queries within and across XML documents. With Oracle XML DB you can express hierarchical queries against XML documents in a familiar, standards compliant manner.

The primary use of XPath in Oracle XML DB is in conjunction with the extract(), extractValue(), and existsNode() functions.

The existsNode() function evaluates whether or not a given document contains a node which matches a W3C XPath expression. The existsNode() function returns true (1) if the document contains the node specified by the XPath expression supplied to the function. The functionality provided by the existsNode() function is also available through the XMLType datatype existNode() method.

See Also:

PurchaseOrder XML Document

Examples in this section are based on the following PurchaseOrder XML document:

<PurchaseOrder 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:noNamespaceSchemaLocation="http://www.oracle.com/xdb/po.xsd">
  <Reference>ADAMS-20011127121040988PST</Reference>
  <Actions>
    <Action>
      <User>SCOTT</User>
      <Date>2002-03-31</Date>
    </Action>
  </Actions>
  <Reject/>
  <Requestor>Julie P. Adams</Requestor>
  <User>ADAMS</User>
  <CostCenter>R20</CostCenter>
  <ShippingInstructions>
    <name>Julie P. Adams</name>
    <address>Redwood Shores, CA 94065</address>
    <telephone>650 506 7300</telephone>
  </ShippingInstructions>
  <SpecialInstructions>Ground</SpecialInstructions>
  <LineItems>
    <LineItem ItemNumber="1">
      <Description>The Ruling Class</Description>
      <Part Id="715515012423" UnitPrice="39.95" Quantity="2"/>
    </LineItem>
    <LineItem ItemNumber="2">
      <Description>Diabolique</Description>
      <Part Id="037429135020" UnitPrice="29.95" Quantity="3"/>
    </LineItem>
    <LineItem ItemNumber="3">
      <Description>8 1/2</Description>
      <Part Id="037429135624" UnitPrice="39.95" Quantity="4"/>
    </LineItem>
  </LineItems>
</PurchaseOrder>

Using existsNode()

The existsNode() syntax is shown in Figure 3-1.

Figure 3-1 existsNode() Syntax

Text description of existsnode.gif follows
Text description of the illustration existsnode.gif


Example 3-4 existsNode() Examples That Find a Node to Match the XPath Expression

Given this sample XML document, the following existsNode() operators return true (1).

SELECT existsNode(value(X),'/PurchaseOrder/Reference')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder[Reference="ADAMS-20011127121040988PST"]')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder/LineItems/LineItem[2]/Part[@Id="037429135020"]')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder/LineItems/LineItem[Description="8 1/2"]')
   FROM XMLTABLE X;    

Example 3-5 existsNode() Examples That Do Not Find a Node that Matches the XPath Expression

The following existsNode() operations do not find a node that matches the XPath expression and all return false(0):

SELECT existsNode(value(X),'/PurchaseOrder/UserName')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder[Reference="ADAMS-XXXXXXXXXXXXXXXXXXXX"]')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder/LineItems/LineItem[3]/Part[@Id="037429135020"]')
   FROM XMLTABLE X;

SELECT existsNode(value(X),
       '/PurchaseOrder/LineItems/LineItem[Description="Snow White"]')
   FROM XMLTABLE X;

The most common use for existsNode() is in the WHERE clause of SQL SELECT, UPDATE, or DELETE statements. In this situation the XPath expression passed to the existsNode() function is used to determine which of the XML documents stored in the table will be processed by the SQL statement.

Example 3-6 Using existsNode() in the WHERE Clause

SELECT count(*)
   FROM XMLTABLE x
   WHERE existsNode(value(x),'/PurchaseOrder[User="ADAMS"]') = 1;  

DELETE FROM XMLTABLE x
   WHERE existsNode(value(x),'/PurchaseOrder[User="ADAMS"]') = 1;  
commit;

The extractValue() function is used to return the value of a text node or attribute associated with an XPath Expression from an XML document stored as an XMLType. It returns a scalar data type.

Using extractValue()

The extractValue() syntax is shown in Figure 3-2.

Figure 3-2 extractValue() Syntax

Text description of extractvalue.gif follows
Text description of the illustration extractvalue.gif


The following are examples of extractValue():

Example 3-7 Valid Uses of extractValue()

SELECT extractValue(value(x),'/PurchaseOrder/Reference')
  FROM XMLTABLE X;

Returns the following:

EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/REFERENCE')
------------------------------------------------------------------------
ADAMS-20011127121040988PST

SELECT extractValue(value(x),
      '/PurchaseOrder/LineItems/LineItem[2]/Part/@Id')
  FROM XMLTABLE X;

Returns the following:

EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM[2]/PART/@ID')
-----------------------------------------------------------------------
037429135020

extractValue() can only return a the value of a single node or attribute value. For instance the following example shows an invalid use of extractValue(). In the first example the XPath expression matches three nodes in the document, in the second example the Xpath expression identifies a nodetree, not a text node or attribute value.

Example 3-8 Non-Valid Uses of extractValue()

SELECT extractValue(value(X),
                   '/PurchaseOrder/LineItems/LineItem/Description')
   FROM XMLTABLE X;

-- FROM XMLTABLE X;
--       *
-- ERROR at line 3:
-- ORA-19025: EXTRACTVALUE returns value of only one node

SELECT extractValue(value(X),
                   '/PurchaseOrder/LineItems/LineItem[1]')
  FROM XMLTABLE X;

-- FROM XMLTABLE X
--    *
-- ERROR at line 3:
-- ORA-19025: EXTRACTVALUE returns value of only one node    

Example 3-9 Using extractValue() in the WHERE Clause

extractValue() can also be used in the WHERE clause of a SELECT, UPDATE, or DELETE statement. This makes it possible to perform joins between XMLType tables or tables containing XMLType columns and other relational tables or XMLType tables. The following query shows you how to use extractValue() in both the SELECT list and the WHERE clause:

SELECT extractValue(value(x),'/PurchaseOrder/Reference')
    FROM XMLTABLE X, SCOTT.EMP
    WHERE extractValue(value(x),'/PurchaseOrder/User') = EMP.ENAME
    AND EMP.EMPNO = 7876;
    
-- This returns:
-- EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/REFERENCE')
-- --------------------------------------------------
-- ADAMS-20011127121040988PST                                

Using extract()

The extract() syntax is shown in Figure 3-3.

Figure 3-3 extract() Syntax

Text description of extract_xml.gif follows
Text description of the illustration extract_xml.gif


extract() is used when the XPath expression will result in a collection of nodes being returned. The nodes are returned as an instance of XMLType. The results of extract() can be either a Document or a DocumentFragment. The functionality of extract is also available through the XMLType datatype's extract() method.

Example 3-10 Using extract() to Return an XML Fragment

The following extract() statement returns an XMLType that contains an XML document fragment containing occurrences of the Description node. These match the specified XPath expression shown.


Note:

In this case the XML is not well formed as it contains more than one root node.


set long 20000

SELECT extract(value(X),
              '/PurchaseOrder/LineItems/LineItem/Description')
  FROM XMLTABLE X;

-- This returns:
-- EXTRACT(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM/DESCRIPTION')
-- ------------------------------------------------------------------
-- <Description>The Ruling Class</Description>
-- <Description>Diabolique</Description>
-- <Description>8 1/2</Description>

Example 3-11 Using extract() to Return a Node Tree that Matches an XPath Expression

In this example extract() returns the node tree that matches the specified XPath expression:

SELECT extract(value(X),
             '/PurchaseOrder/LineItems/LineItem[1]')
  FROM XMLTABLE X;

This returns:

EXTRACT(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM[1]')
-------------------------------------------------------------------------
<LineItem ItemNumber="1">
  <Description>The Ruling Class</Description>
  <Part Id="715515012423" UnitPrice="39.95" Quantity="2"/>
</LineItem>                    

Using XMLSequence()

The XMLSequence() syntax is shown in Figure 3-4.

Figure 3-4 XMLSequence() Syntax

Text description of XMLSequence.gif follows
Text description of the illustration XMLSequence.gif


An XML document fragment can be converted into a set of XMLTypes using the XMLSequence() function. XMLSequence() takes an XMLType containing a document fragment and returns a collection of XMLType objects. The collection will contain one XMLType for each root level node in the fragment. The collection can then be converted into a set of rows using the SQL TABLE function.

Example 3-12 Using XMLSequence() and TABLE() to Extract Description Nodes from an XML Document

The following example shows how to use XMLSequence() and Table() to extract the set of Description nodes from the purchaseorder document.

set long 10000
set feedback on
SELECT extractValue(value(t),'/Description')
  FROM XMLTABLE X, 
    TABLE ( xmlsequence (
           extract(value(X),
                 '/PurchaseOrder/LineItems/LineItem/Description')
           )
  ) t;

This returns:

EXTRACTVALUE(VALUE(T),'/DESCRIPTION')
-------------------------------------------------------------------------
The Ruling Class
Diabolique
8 1/2

Updating XML Documents with updateXML()

The updateXML() syntax is shown in Figure 3-5.

Figure 3-5 updateXML() Syntax

Text description of updatexml.gif follows
Text description of the illustration updatexml.gif


You can update XML documents using the updateXML() function. updateXML() updates an attribute value, node, text node, or node tree. The target for the update operation is identified using an XPath expression. The following examples show how you can use updateXML() to modify the contents of an XML Document stored as an XMLType.

Example 3-13 Using updateXML() to Update a Text Node Value Identified by an XPath Expression

This example uses updateXML() to update the value of the text node identified by the XPath expression `/PurchaseOrder/Reference':

UPDATE XMLTABLE t
    SET value(t) = updateXML(value(t),
                           '/PurchaseOrder/Reference/text()',
                           'MILLER-200203311200000000PST')
    WHERE existsNode(value(t),
       '/PurchaseOrder[Reference="ADAMS-20011127121040988PST"]') = 1;

This returns:

1 row updated.

SELECT value(t)
   FROM XMLTABLE t;

This returns:

VALUE(T)
-------------------------------------------------------------------------
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
       xsi:noNamespaceSchemaLocation="http://www.oracle.com/xdb/po.xsd">
  <Reference>MILLER-200203311200000000PST</Reference>
...
</PurchaseOrder> 

Example 3-14 Using updateXML() to Replace Contents of a Node Tree Associated with XPath Elements

In this example updateXML() replaces the contents of the node tree associated with the element identified by the XPath expression `/PurchaseOrders/LineItems/LineItem[2]'.


Note:

In this example, since the replacement value is a Node tree, the third argument to the updateXML() function is supplied as an instance of the XMLType datatype.


UPDATE XMLTABLE t
  SET value(t) = 
  updateXML(value(t),
            '/PurchaseOrder/LineItems/LineItem[2]',
            xmltype('<LineItem ItemNumber="4">
                       <Description>Andrei Rublev</Description>
                       <Part Id="715515009928" UnitPrice="39.95"
                             Quantity="2"/>
                     </LineItem>'
             )
  )
  WHERE existsNode(value(t),
        '/PurchaseOrder[Reference="MILLER-200203311200000000PST"]'
  ) = 1;

This returns:

1 row updated.

SELECT value(t)
  FROM XMLTABLE t;

And this returns:

VALUE(T)
------------------------------------------------------------------------
<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNames
paceSchemaLocation="http://www.oracle.com/xdb/po.xsd">
  <Reference>MILLER-200203311200000000PST</Reference>
...
  <LineItems>
    <LineItem ItemNumber="1">
      <Description>The Ruling Class</Description>
      <Part Id="715515012423" UnitPrice="39.95" Quantity="2"/>
    </LineItem>
    <LineItem ItemNumber="4">
      <Description>Andrei Rublev</Description>
      <Part Id="715515009928" UnitPrice="39.95" Quantity="2"/>
    </LineItem>
    <LineItem ItemNumber="3">
      <Description>8 1/2</Description>
      <Part Id="037429135624" UnitPrice="39.95" Quantity="4"/>
    </LineItem>
  </LineItems>
</PurchaseOrder>  

Introducing the W3C XSLT Recommendation

The W3C XSLT Recommendation defines an XML language for specifying how to transform XML documents from one form to another. Transformation can include mapping from one XML schema to another or mapping from XML to some other format such as HTML or WML.

See Also:

Appendix D, "XSLT Primer" for an introduction to the W3C XSL and XSLT recommendations.

Example 3-15 XSL Stylesheet Example: PurchaseOrder.xsl

The following example, PurchaseOrder.xsl, is an example fragment of an XSL stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"  
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:xdb="http://xmlns.oracle.com/xdb" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <xsl:template match="/">
    <html>
      <head/>
      <body bgcolor="#003333" text="#FFFFCC" link="#FFCC00"             
            vlink="#66CC99" alink="#669999">
        <FONT FACE="Arial, Helvetica, sans-serif">
          <xsl:for-each select="PurchaseOrder"/>
          <xsl:for-each select="PurchaseOrder">
            <center>
              <span style="font-family:Arial; font-weight:bold">
                <FONT COLOR="#FF0000">
                  <B>Purchase Order </B>
                </FONT>
              </span>
            </center>
            <br/>
         ...
                        <FONT FACE="Arial, Helvetica, sans-serif" 
                              COLOR="#000000">
                          <xsl:for-each select="Part">
                            <xsl:value-of select="@Quantity*@UnitPrice"/>
                          </xsl:for-each>
                        </FONT>
                      </td>
                    </tr>
                  </tbody>
                </xsl:for-each>
              </xsl:for-each>
            </table>
          </xsl:for-each>
        </FONT>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
See Also:

Appendix D, "XSLT Primer" for the full listing of this XSL stylesheet.

Using XSL/XSLT with Oracle XML DB

Oracle XML DB complies with the W3C XSL/XSLT recommendation by supporting XSLT transformations in the database. In Oracle XML DB, XSLT transformations can be performed using either of the following:

Since XSL stylesheets are valid XML documents both approaches apply when the XSL stylesheets are provided as instances of the XMLType datatype. The results of the XSL transformation are also returned as an XMLType.

Because the transformation takes place close to the data, Oracle XML DB can optimize features such as memory usage, I/O operations, and network traffic required to perform the transformation.

See Also:

Chapter 6, "Transforming and Validating XMLType Data"

Example 3-16 Using transform() to Transform an XSL

The following example shows how transform() can apply XSLT to an XSL stylesheet, PurchaseOrder.xsl, to transform the PurchaseOrder.xml document:

SELECT value(t).transform(xmltype(getDocument('purchaseOrder.xsl')))
    from XMLTABLE t
    where existsNode(value(t),
                     '/PurchaseOrder[Reference="MILLER-200203311200000000PST"]'
    ) = 1;

This returns:

VALUE(T).TRANSFORM(XMLTYPE(GETDOCUMENT('PURCHASEORDER.XSL')))
-------------------------------------------------------------------------
<html>
  <head/>
  <body bgcolor="#003333" text="#FFFFCC" link="#FFCC00" vlink="#66CC99" alink="#
669999">
    <FONT FACE="Arial, Helvetica, sans-serif">
      <center>                                 
...
    </FONT>
  </body>
</html>

Since the transformed document using XSLT is expected as in instance of XMLType, the source could easily be a database table.

Other XMLType Methods

The following describes additional XMLType methods:

Introducing the W3C XML Schema Recommendation

XML Schema provides a standardized way of defining what the expected contents of a set of XML documents should be. An XML schema is a an XML document that defines metadata. This metadata specifies what the member contents of the document class should be. The members of a document class can be referred to as instance documents.

Since an XML schema definition is simply an XML document that conforms to the class defined by the XML Schema http://www.w3.org/2001/XMLSchema, XML schemas can be authored using a simple text editor, such as Notepad, vi, a schema-aware editor, such as the XML editor included with the Oracle9i JDeveloper tool, or an explicit XML schema authoring tool, such as XMLSpy from Altova Corporation. The advantage of using a tool such as XMLSpy, is that these tools allow the XML schema to be developed using an intuitive, graphical editor which hides much of the details of the XML schema definition from the developer.

Example 3-17 XML Schema Example, PurchaseOrder.xsd

The following example PurchaseOrder.xsd, is a standard W3C XML Schema example fragment, in its native form, as an XML Document:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:complexType name="ActionsType" >
                <xs:sequence>
                        <xs:element name="Action" maxOccurs="4" >
                                <xs:complexType >
                                        <xs:sequence>
                                                <xs:element ref="User"/>
                                                <xs:element ref="Date"/>
                                        </xs:sequence>
                                </xs:complexType>
                        </xs:element>
                </xs:sequence>
        </xs:complexType>
        <xs:complexType name="RejectType" >
                <xs:all>
                        <xs:element ref="User" minOccurs="0"/>
                        <xs:element ref="Date" minOccurs="0"/>
                        <xs:element ref="Comments" minOccurs="0"/>
                </xs:all>
        </xs:complexType>
        <xs:complexType name="ShippingInstructionsType" >
                <xs:sequence>
                        <xs:element ref="name"/>
                        <xs:element ref="address"/>
                        <xs:element ref="telephone"/>
                </xs:sequence>
...
....
                <xs:complexType>
                        <xs:attribute name="Id" >
                                <xs:simpleType>
                                        <xs:restriction base="xs:string">
                                            <xs:minLength value="12"/>
                                            <xs:maxLength value="14"/>
                                        </xs:restriction>
                                </xs:simpleType>
                        </xs:attribute>
                        <xs:attribute name="Quantity" type="money"/>
                        <xs:attribute name="UnitPrice" type="quantity"/>
                </xs:complexType>
        </xs:element>
</xs:schema>
See Also:

Appendix B, "XML Schema Primer" for the detailed listing of PurchaseOrder.xsd.

Using XML Schema with Oracle XML DB

Oracle XML DB supports the use of the W3C XML Schema in two ways.

To use a W3C XML Schema with Oracle XML DB, the XML schema document has to be registered with the database. Once an XML schema has been registered XMLType tables and columns can be created which are bound to the schema.

To register an XML schema you must provide two items. The first is the XMLSchema document, the second is the URL which will be used by XML documents which claim to conform to this Schema. This URL will be provided in the root element of the instance document using either the noNamespaceSchemaLocation attribute or schemaLocation attribute as defined in the W3C XML Schema recommendation

XML schemas are registered using methods provided by PL/SQL package DBMS_XMLSCHEMA. Schemas can be registered as global or local schemas. See Chapter 5, "Structured Mapping of XMLType" for a discussion of the differences between Global and Local Schemas.

Oracle XML DB provides a number of options for automatically generating default database objects and Java classes as part of the schema registration process. Some of these options are discussed later in this section.

Example 3-18 Registering PurchaseOrder.xsd as a Local XML Schema Using registerSchema()

The following example shows how to register the preceding PurchaseOrder.xsd XML schema as a local XML schema using the registerSchema() method.

begin
    dbms_xmlschema.registerSchema(
                   'http://www.oracle.com/xsd/purchaseOrder.xsd',
                   getDocument('PurchaseOrder.xsd'),
                   TRUE, TRUE, FALSE, FALSE
    );
end;
/

--This returns:
-- PL/SQL procedure successfully completed.

The registerSchema() procedure causes Oracle XML DB to perform the following operations:

Once the XML schema has been registered with Oracle XML DB, it can be referenced when defining tables that contain XMLType columns, or creating XMLType tables.

Example 3-19 Creating an XMLType Table that Conforms to an XML Schema

This example shows how to create an XMLType table which can only contain XML Documents that conform to the definition of the PurchaseOrder element in the XML schema registered at `http://www.oracle.com/xsd/purchaseorder.xsd'.

CREATE TABLE XML_PURCHASEORDER of XMLType
   XMLSCHEMA "http://www.oracle.com/xsd/purchaseOrder.xsd"
   ELEMENT "PurchaseOrder";

This results in:

Table created.

DESCRIBE XML_PURCHASEORDER

Returns the following:

Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
TABLE of SYS.XMLTYPE(XMLSchema "http://www.oracle.com/xsd/purchaseOrder.xsd" 
Element "PurchaseOrder") STORAGE Object-relational TYPE "PurchaseOrder538_T"

XMLSchema-Instance Namespace

Oracle XML DB must recognize that the XML document inserted into an XML schema-based table or column is a valid member of the class of documents defined by the XML schema. The XML document must correctly identify the XML schema or XML schemas it is associated with.

This means that XML schema, for each namespace used in the document, must be identified by adding the appropriate attributes to the opening tag for the root element of the document. These attributes are defined by W3C XML Schema recommendation and are part of the W3C XMLSchema-Instance namespace. Consequently in order to define these attributes the document must first declare the XMLSchema-instance namespace. This namespace is declared as follows: xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance:

Once the XMLSchema-instance namespace has been declared and given a namespace prefix the attributes that identify the XML schema can be added to the root element of the instance document. A given document can be associated with one or more XML schemas. In the preceding example, the namespace prefix for the XMLSchema-instance namespace was defined as xsi.

noNameSpaceSchemaLocation Attribute.

The XML schema associated with the unqualified elements is defined using the attribute noNamespaceSchemaLocation. In the case of the PurchaseOrder.xsd XML schema, the correct definition would be as follows:

<PurchaseOrder
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
  xsi:noNamespaceSchemaLocation="http://www.oracle.com/xsd/purchaseOrder.xsd"> 
Using Multiple Namespaces: schemaLocation Attribute.

If the XML document uses multiple namespaces then each namespace needs to be identified by a schemaLocation attribute. For example, assuming that the Purchaseorder document used the namespace PurchaseOrder, and the PurchaseOrder namespace is given the prefix po. The definition of the root element of a PurchaseOrder document would then be as follows:

<po:PurchaseOrder
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:po="PurchaseOrder"
xsi:schemaLocation="PurchaseOrder http://www.oracle.com/xsd/purchaseOrder.xsd">

Validating an XML Document Using an XML Schema

By default Oracle XML DB performs a minimum amount of validation when a storing an instance document. This minimal validation ensures that the structure of the XML document conforms to the structure specified in the XML schema.

Example 3-20 Attempting to Insert an Invoice XML Document Into an XMLType Table Conforming to PurchaseOrder XML Schema

The following example shows what happens when an attempt is made to insert an XML Document containing an invoice into a XMLType table that is defined as storing documents which conform to the PurchaseOrder Schema

INSERT INTO XML_PURCHASEORDER
   values (xmltype(getDocument('Invoice.xml')))
  values (xmltype(getDocument('Invoice.xml')))
        *

This returns:

ERROR at line 2:
ORA-19007: Schema and element do not match  

The reason for not performing full instance validation automatically is based on the assumption that, in the majority of cases it is likely that schema based validation will have been performed prior to attempting to insert the XML document into the database.

In situations where this is not the case, full instance validation can be enabled using one of the following approaches:

Example 3-21 Using CHECK Constraints in XMLType Tables

This example shows how to use a CHECK constraint to an XMLType table and the result of attempting to insert an invalid document into the table:

ALTER TABLE XML_PURCHASEORDER
   add constraint VALID_PURCHASEORDER
   check (XMLIsValid(sys_nc_rowinfo$)=1);

-- This returns:   
-- Table altered

INSERT INTO XML_PURCHASEORDER
   values (xmltype(getDocument('InvalidPurchaseOrder.xml')));
INSERT INTO XML_PURCHASEORDER;
*
-- This returns:
-- ERROR at line 1:
-- ORA-02290: check constraint (DOC92.VALID_PURCHASEORDER) violated

Example 3-22 Using BEFORE INSERT Trigger to Validate Data Inserted Into XMLType Tables

The next example shows how to use a BEFORE INSERT trigger to validate that the data being inserted into the XMLType table conforms to the specified schema

CREATE TRIGGER VALIDATE_PURCHASEORDER
    before insert on XML_PURCHASEORDER
    for each row
    declare
      XMLDATA xmltype;
    begin
       XMLDATA := :new.sys_nc_rowinfo$;
       xmltype.schemavalidate(XMLDATA);
    end;
/

-- This returns: 
-- Trigger created.

insert into XML_PURCHASEORDER
   values (xmltype(getDocument('InvalidPurchaseOrder.xml')));
   
-- values (xmltype(getDocument('InvalidPurchaseOrder.xml')))
--        *
-- ERROR at line 2:
-- ORA-31154: invalid XML document
-- ORA-19202: Error occurred in XML processing
-- LSX-00213: only 0 occurrences of particle "User", minimum is 1
-- ORA-06512: at "SYS.XMLTYPE", line 0
-- ORA-06512: at "DOC92.VALIDATE_PURCHASEORDER", line 5
-- ORA-04088: error during execution of trigger 'DOC92.VALIDATE_PURCHASEORDER'

As can be seen both approaches ensure that only valid XML documents can be stored in the XMLType table:

Storing XML: Structured or Unstructured Storage

When designing an Oracle XML DB application you must first decide whether the XMLType columns and table will be stored using structured or unstructured storage techniques.

Table 3-1 compares using structured and structured storage to store XML.

Table 3-1 Comparing Structured and Unstructured XML Storage  
Feature Unstructured XML Storage Structured XML Storage

Storage technique

Contents of XMLType columns and tables are stored using the CLOB data type.

Contents of XMLType columns and tables are stored as a collection of SQL objects. By default, the underlying storage model for XML schema-based XMLType columns and tables is structured storage.

Can store non-XML schema-based tables?

Only option available for XMLType tables and columns that are not associated with an XML schema.

Can only be used when the XMLType column or table is based on an XML schema. This means that the instance documents must conform to the underlying XML schema.

Performance: Storage and retrieval speed

It allows for higher rates of ingestion and retrieval, as it avoids the overhead associated with parsing and recomposition during storage and retrieval operations.

Results in a slight overhead during ingestion and retrieval operations in that the document has to be shredded during ingestion and re-constituted prior to retrieval.

Performance: operation speed

Slower than for structured storage.

When an XML schema is registered, Oracle XML DB generates a set of SQL objects that correspond to complexTypes defined in the XML schema. XPath expressions sent to Oracle XML DB functions are translated to SQL statements that operate directly against the underlying objects.

This re-writing of XMLType operations into object-relational SQL statements results in significant performance improvements compared with performing the same operations against XML documents stored using unstructured storage.

Flexible. Can easily process varied content?

Allows for a great deal of flexibility in the documents being processed making it an appropriate choice when the XML documents contain highly variable content.

Leverages the object-relational capabilities of the Oracle9i database.

Memory usage: Do the XML documents need parsing?

Oracle XML DB must parse the entire XML document and load it into an in-memory DOM structure before any validation, XSL Transformation, or XPath operations can be performed on it.

Allows Oracle XML DB to minimize memory usage and optimize performance of DOM-based operations on XMLType table and columns by using:

  • Lazy Manifestation (LM): Occurs when Oracle XML DB constructs a DOM structure based on an XML document. With LM, instead of constructing the whole DOM when the document is accessed, Oracle XML DB only instantiates the nodes required to perform the immediate operation. As other parts of the document are required the appropriate node trees are dynamically loaded into the DOM.
  • Least Recently Used (LRU): Strategy to discard nodes in the DOM that have not been accessed recently.

Update processing

When stored, any update operations on the document will result in the entire CLOB being re-written.

If any part of the document is updated using updateXML() then the entire document has to be fetched from the CLOB, updated, and written back to the CLOB.

Can update individual elements, attributes, or nodes in an XML document without rewriting the entire document.

Possible to re-write the updateXML() operation to an SQL UPDATE statement that operates on columns or objects referenced by the XPATH expression.

Indexing

You can use B*Tree indexes based on the functional evaluation of XPath expressions or Oracle Text inverted list indexes.

Unstructured storage make it impossible to create B*TREE indexes based on the values of elements or attributes that appear within collections.

You can use B*Tree indexes and Oracle Text inverted list indexes.

By tuning the way in which collections are managed, indexes can be created on any element or attribute in the document, including elements or attributes that appear with collections.

Space needed

Can be large.

Since based on XML schema, it is not necessary for Oracle XML DB to store XML tag names when storing the contents of XML documents. This can significantly reduce the storage space required.

Data integrity

--

Makes it possible to use a set of database integrity constraints that allow the contents of an XML document to be validated against information held elsewhere in the database.

Tuning: Fine-grained object control

None

You can annotate XML schema, for fine grain control over sets of SQL objects generated from XML schema and how these objects are stored in the database.

You can control how collections are managed, define tablespace usage, and partitioning of table or tables used to store and manage the SQL objects. This makes it possible to fine tune the performance of the Oracle XML DB to meet the needs of the application.

Other annotations control how Simple elements and attributes are mapped to SQL columns

Data Manipulation Language (DML) Independence

Oracle XML DB ensures that all Data Manipulation Language (DML) operations based on Oracle XML DB functions return consistent results. By abstracting the storage model through the use of the XMLType datatype, and providing a set of operators that use XPath to perform operations against XML documents, Oracle XML DB makes it possible for you to switch between structured and unstructured storage, and to experiment with different forms of structured storage without affecting the application.

DOM Fidelity in Structured and Unstructured Storage

To preserve DOM fidelity a system must ensure that a DOM generated from the stored representation of an XML Document is identical to a DOM generated from the original XML document. Preserving DOM integrity ensures that none of the information contained in the XML Document is lost as a result of storing it.

The problem with maintaining DOM integrity is that an XML document can contain a lot of information in addition to the data contained in element and attribute values. Some of this information is explicitly provided, using Comments and Processing Instructions. Other information can be implicitly provided, such as:

One of the common problems application developers face when using a traditional relational model to manage the contents of XML documents is how to preserve this information. Table 3-2 compares DOM fidelity in structured and unstructured storage:

Table 3-2 DOM Fidelity: Unstructured and Structured Storage
DOM Fidelity with Unstructured Storage DOM Fidelity with Structured Storage

Relational systems do not provide any implicit ordering, nor do they provide the flexibility to make it easy to preserve out of band data such as comments and processing instructions. With a typical relational database, the only way to preserve DOM Fidelity is to store the source document using unstructured storage techniques

Oracle XML DB can preserve DOM Fidelity even with structured storage. When an XML Document is shredded and stored using structured storage techniques, the Comments, Processing Instructions, and any ordering information implicit in the source document is preserved as part of the SQL objects that are created when the document is shredded. When the document is retrieved this information is incorporated back into the generated XML document.

Structured Storage: XML Schema-Based Storage of XMLType

Logically, an XML document consists of a collection of elements and attributes. Elements can be either of the following:

An XML schema defines the set of elements and attributes that can exist in a particular class of XML document and defines the relationships between them.

During XML schema registration, Oracle XML DB generates an SQL Object Type for each complexType defined in the XML schema. The definition of the SQL object mirrors the definition of the complexType.

Each child element and attribute defined by the complexType maps to an attribute of the SQL object type.

XML Schema Names and Defining Oracle XML DB Namespace

By default SQL Objects generated when an XML schema is registered are given system-generated names. However, with Oracle XML DB you can specify the names of SQL objects by annotating the schema. To annotate an XML schema, you must first include the Oracle XML DB namespace in the XMLSchema tag, defined as:

http://xmlns.oracle.com/xdb

Hence an XML schema using Oracle XML DB annotations, must contain the following attributes in the XMLSchema tag:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xdb="http://xmlns.oracle.com/xdb" >
...
</xs:schema>

Once Oracle XML DB namespace has been defined, the annotations defined by Oracle XML DB can be used.

Example 3-23 Defining the Name of SQL Objects Generated from complexTypes

This example uses xdb:SQLType to define the name of the SQL object generated from complexType PurchaseOrder, as XML_PURCHASEORDER_TYPE.

<xs:element name="PurchaseOrder">
    <xs:complexType type="PurchaseOrderType"
                    xdb:SQLType="XML_PURCHASEORDER_TYPE">
        <xs:sequence>
            <xs:element ref="Reference"/>
            <xs:element name="Actions" type="ActionsType"/>
            <xs:element name="Reject" type="RejectType" minOccurs="0"/>
            <xs:element ref="Requestor"/>
            <xs:element ref="User"/>
            <xs:element ref="CostCenter"/>
            <xs:element name="ShippingInstructions"
                        type="ShippingInstructionsType"/>
            <xs:element ref="SpecialInstructions"/>
            <xs:element name="LineItems" type="LineItemsType"/>
       </xs:sequence>
    </xs:complexType>
</xs:element>                     

So executing the following statement:

DESCRIBE XML_PURCHASEORDER_TYPE
 XML_PURCHASEORDER_TYPE is NOT FINAL;

Returns the following structure:

Name                           Null?    Type
------------------------------ -------- ----------------------------
SYS_XDBPD$                              XDB.XDB$RAW_LIST_T
Reference                               VARCHAR2(26)
Actions                                 XML_ACTIONS_TYPE
Reject                                  XML_REJECTION_TYPE
Requestor                               VARCHAR2(128)
User                                    VARCHAR2(10)
CostCenter                              VARCHAR2(4)
ShippingInstructions                    XML_SHIPPINGINSTRUCTIONS_TYPE
SpecialInstructions                     VARCHAR2(2048)
LineItems                               XML_LINEITEMS_TYPE


Note:

In the preceding example, xdb:SQLType annotation was also used to assign names to the SQL types that correspond to the complexTypes: ActionsType, ShippingInstructionsType and LineItemsType.


Using xdb:SQLName to Override Default Names

Oracle XML DB uses a predefined algorithm to generate valid SQL names from the names of the XML elements, attributes, and types defined in the XML schema. The xdb:SQLName annotation can be used to override the default algorithm and supply explicit names for these items.

Using xdb:SQLType to Override Default Mapping

Oracle XML DB also provides a default mapping between scalar datatypes defined by the XML Schema recommendation and the primitive datatype defined by SQL. Where possible the size of the SQL datatype is derived from restrictions defined for the XML datatype. If required, the xdb:SQLType annotation can be used to override this default mapping:

Example 3-24 Using xdb:SQLType and xdb:SQLName to Specify the Name and Mapping of Objects Generated from complexTypes

This example shows how to override the name and type used for the SpecialInstructions element and the effect these changes have on the generated SQL Object type.


Note:

The override for the name of the SpecialInstructions element is applied where the element is used, inside the PurchaseOrderType, not where it is defined


<xs:element name="SpecialInstructions" xdb:SQLType="CLOB"  >
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
            <xs:maxLength value="2048"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>  

<xs:element name="PurchaseOrder">
    <xs:complexType type="PurchaseOrderType"
                    xdb:SQLType="XML_PURCHASEORDER_TYPE">
        <xs:sequence>
            <xs:element ref="Reference"/>
            <xs:element name="Actions" type="ActionsType"/>
            <xs:element name="Reject" type="RejectType" minOccurs="0"/>
            <xs:element ref="Requestor"/>
            <xs:element ref="User"/>
            <xs:element ref="CostCenter"/>
            <xs:element name="ShippingInstructions"
                        type="ShippingInstructionsType"/>
            <xs:element ref="SpecialInstructions"
                        xdb:SQLName="SPECINST"/>
            <xs:element name="LineItems" type="LineItemsType"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>  

On executing the following statement:

DESCRIBE XML_PURCHASEORDER_TYPE
 XML_PURCHASEORDER_TYPE is NOT FINAL

The following structure is returned:

Name                           Null?    Type
------------------------------ -------- ----------------------------
SYS_XDBPD$                              XDB.XDB$RAW_LIST_T
Reference                               VARCHAR2(26)
Actions                                 XML_ACTIONS_TYPE
Reject                                  XML_REJECTION_TYPE
Requestor                               VARCHAR2(128)
User                                    VARCHAR2(10)
CostCenter                              VARCHAR2(4)
ShippingInstructions                    XML_SHIPPINGINSTRUCTIONS_TYPE
SPECINST                                CLOB  
LineItems                               XML_LINEITEMS_TYPE

Structured Storage: Storing complexType Collections

One issue you must consider when selecting structured storage, is what techniques to use to manage Collections. Different approaches are available and each approach offers different benefits. Generally, you can handle Collections in five ways:

Structured Storage: Data Integrity and Constraint Checking

In addition to schema-validation, structured storage makes it possible to introduce traditional relational constraints on to XMLType columns and Tables. With database integrity checking you can perform instance validation beyond what is achievable with XML Schema-based validation.

The W3C XML Schema Recommendation only allows for validation based on cross-referencing of values with an instance document. With database integrity checking you can enforce other kinds of validation, such as enforcing the uniqueness of a element or attribute across a collection of documents, or validating the value of a element or attribute against information stored elsewhere in the database.


Note:

In Oracle9i Release 2 (9.2) constraints have to be specified using object-relational syntax.


Example 3-25 Adding a Unique and Referential Constraint to Table Purchaseorder

The following example shows how you can introduce a Unique and Referential Constraint on the PurchaseOrder table.

XMLDATA.SQLAttributeName
alter table XML_PURCHASEORDER
add constraint REFERENCE_IS_UNQIUE 
-- unique(extractValue('/PurchaseOrder/Reference'))
unique (xmldata."Reference");

alter table XML_PURCHASEORDER
add constraint USER_IS_VALID
-- foreign key extractValue('/PurchaseOrder/User') references
SCOTT.EMP(ENAME)
foreign key (xmldata."User") references SCOTT.EMP(ENAME);

As can be seen, when an attempt is made to insert an XML Document that contains a duplicate value for the element /PurchaseOrder/Reference into the table, the database detects that the insert would violate the unique constraint, and raises the appropriate error.

insert into xml_purchaseorder values (
   xmltype(getDocument('ADAMS-20011127121040988PST.xml'))
   );

This returns:

1 row created.

insert into xml_purchaseorder values (
  xmltype(getDocument('ADAMS-20011127121040988PST.xml'))
  );

insert into xml_purchaseorder values (
*

This returns:

ERROR at line 1:
ORA-00001: unique constraint (DOC92.REFERENCE_IS_UNQIUE) violated

Example 3-26 How Oracle9i Database Enforces Referential Constraint User_Is_Valid

The following example shows how the database will enforce the referential constraint USER_IS_VALID, which states that the value of the element /PurchaseOrder/User, that translates to the SQLAttribute xmldata.user", must match one of the values of ENAME in SCOTT.EMP.

insert into xml_purchaseorder values (
   xmltype(getDocument('HACKER-20011127121040988PST.xml'))
   );

insert into xml_purchaseorder values (
*

This returns:

ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.USER_IS_VALID) 
violated - parent key notfound

Oracle XML DB Repository

XML documents are by nature hierarchical animals. The information they contain is represented by a hierarchy of elements, child elements, and attributes. XML documents also view the world around them as a hierarchy. When an XML document refers to another XML document, or any other kind of document, it does so using a URL. URLs can be either relative or absolute. In either case, the URL defines a path to the target document. The path is expressed in terms of a folder hierarchy.

Oracle XML DB Repository makes it possible to view all of XML content stored in the database using a File / Folder metaphor. The Repository provides support for basic operations such as creating files and folders as well as more advanced features such as version and access control.

The Repository is fully accessible, queryable, and updatable through SQL. It can also be directly accessed through industry standard protocols such as HTTP, WebDAV, and FTP.

See Also:

Chapter 13, "Oracle XML DB Foldering"

Introducing the IETF WebDAV Standard

WebDAV is an Internet Engineering Task Force (IETF) Standard for Distributed Authoring and Versioning of content. The standard is implemented by extending the HTTP protocol allowing a Web Server to act as a File Server in a distributed environment.

Oracle XML DB Repository is Based on WebDAV

Oracle XML DB Repository is based on the model defined by the WebDAV standard. It uses the WebDAV resource model to define the basic metadata that is maintained for each document stored in the Repository. The WebDAV protocol uses XML to transport metadata between the client and the server.

Hence, you can easily create, edit, and access documents stored in Oracle XML DB Repository using standard tools. For example, you can use:

WebDAV uses the term Resource to define a file or folder. It defines a set of basic operations that can be performed on a Resource. These operations require a WebDAV server to maintain a set of basic metadata for each Resource. Oracle XML DB exposes this metadata as a set of XML Documents in the following form:

Example 3-27 Oracle XML DB Exposes WebDAV Resource Metadata as XML Documents

<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"     
          Hidden="false" Invalid="false" Container="false"
          CustomRslv="false">
  <CreationDate> 2002-02-14T16:01:01.066324000</CreationDate>
  <ModificationDate> 2002-02-14T16:01:01.066324000</ModificationDate>
  <DisplayName>testFile.xml</DisplayName>
  <Language>us english</Language>
  <CharacterSet>utf-8</CharacterSet>
  <ContentType>text/xml</ContentType>
  <RefCount>1</RefCount>
  <ACL>
    <acl description="/sys/acls/all_all_acl.xml"
         xmlns="http://xmlns.oracle.com/xdb/acl.xsd" 
         xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
         xsi:schemaLocation="http://xmlns.oracle.com/xdb/acl.xsd                           
                             http://xmlns.oracle.com/xdb/acl.xsd">
      <ace>
        <grant>true</grant>
        <privilege>
          <all/>
        </privilege>
        <principal>PUBLIC</principal>
      </ace>
    </acl>
  </ACL>
  <Owner>DOC92</Owner>
  <Creator>DOC92</Creator>
  <LastModifier>DOC92</LastModifier>
  <SchemaElement>
     http://xmlns.oracle.com/xdb/XDBSchema.xsd#binary
   </SchemaElement>
  <Contents>
    <binary>02C7003802C77B7000081000838B1C240000000002C71E7C</binary>
  </Contents>
</Resource>  

Query-Based Access to Oracle XML DB Repository

Oracle XML DB exposes the Repository to SQL developers as two views:

It also provides a set of SQL functions and PL/SQL packages for performing Repository operations.

See Also:

Chapter 15, "RESOURCE_VIEW and PATH_VIEW"

Using RESOURCE_VIEW

RESOURCE_VIEW is the primary way for querying Oracle XML DB Repository. There is one entry in the RESOURCE_VIEW for each document stored in the Repository. The RES column contains the resource entry for the document, the ANY_PATH entry provides a valid folder path from the root to the resource.

The definition of the RESOURCE_VIEW is:

SQL> describe RESOURCE_VIEW

 Name                           Null?    Type
------------------------------- -------- ----------------------------
 RES                                     SYS.XMLTYPE
 ANY_PATH                                VARCHAR2(4000)

Using PATH_VIEW

PATH_VIEW contains an entry for each Path in the Repository. Since a Resource can be linked into more than one folder, PATH_VIEW shows all possible Paths in the Repository and the resources they point to. The definition of the PATH_VIEW is:

SQL> describe PATH_VIEW

 Name                           Null?    Type
------------------------------- -------- ----------------------------
 PATH                                    VARCHAR2(1024)
 RES                                     SYS.XMLTYPE
 LINK                                    SYS.XMLTYPE  

Creating New Folders and Documents

You can create new folders and documents using methods provided by DBMS_XDB package. For example, a new folder can be created using the procedure createFolder() and a file can be uploaded into that folder using createResource(). The following examples show you how to do this:

Example 3-28 Creating a Repository Resource and Folder

SQL> declare
  2    result boolean;
  3  begin
  4    result := dbms_xdb.createFolder('/public/testFolder');
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL> declare
  2    result boolean;
  3  begin
4    result := dbms_xdb.createResource(
5                       '/public/testFolder/testFile.xml',
6                       getDocument('testFile.xml')
7    );
  8  end;
  9  /

PL/SQL procedure successfully completed.       

Querying Resource Documents

RESOURCE_VIEW can be queried just like any other view. Oracle XML DB provides a new operator, UNDER_PATH, that provides a way for you to restrict queries to a particular folder tree within the RESOURCE_VIEW.

extractValue() and existsNode() can be used on the Resource documents when querying the RESOURCE_VIEW and PATH_VIEW Resource documents.

Updating Resources

You can update Resources using updateXML().

Example 3-29 Updating Repository Resources

For example, the following query updates the OWNER and NAME of the document created in the previous example.

update RESOURCE_VIEW
  set RES=updateXML(RES,
                    '/Resource/DisplayName/text()','RenamedFile',
                    '/Resource/Owner/text()','SCOTT'
 )
where any_path = '/public/testFolder/testFile.xml';

-- 1 row updated.

select r.res.getClobVal()
   from RESOURCE_VIEW r
   where ANY_PATH = '/public/testFolder/testFile.xml'
/

-- Results in:
-- R.RES.GETCLOBVAL()
-- ----------------------------------------------------------------------
-- <Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"     
--           Hidden="false" Invalid="false" Container="false"
--           CustomRslv="false">
--   <CreationDate> 2002-02-14T16:01:01.066324000</CreationDate>
--   <ModificationDate> 2002-02-14T21:36:39.579663000</ModificationDate>
--   <DisplayName>RenamedFile</DisplayName>
--   <Language>us english</Language>
--   <CharacterSet>utf-8</CharacterSet>
--   <ContentType>text/xml</ContentType>
-- <RefCount>1</RefCount>
-- <ACL>
-- ...
-- </ACL>
--   <Owner>SCOTT</Owner>
--   <Creator>DOC92</Creator>
--  <LastModifier>DOC92</LastModifier>
-- </Resource>

Deleting Resources

Resource can be deleted using deleteResource(). If the resource is a folder then the folder must be empty before it can be deleted.

Example 3-30 Deleting Repository Resources

The following examples show the use of the deleteResource() procedure.

call dbms_xdb.deleteResource('/public/testFolder')
   /
call dbms_xdb.deleteResource('/public/testFolder')
     *
ERROR at line 1:
ORA-31007: Attempted to delete non-empty container /public//testFolder
ORA-06512: at "XDB.DBMS_XDB", line 151
ORA-06512: at line 1

call dbms_xdb.deleteResource('/public/testFolder/testFile.xml')
 /
Call completed.

call dbms_xdb.deleteResource('/public/testFolder')
/
Call completed.     

Storage Options for Resources

RESOURCE_VIEW and PATH_VIEW are based on tables stored in Oracle XML DB database schema. The metadata exposed through RESOURCE_VIEW and PATH_VIEW is stored and managed using a set of tables in Oracle XML DB-supplied XML schema, XDBSchema.xsd. The contents of the files are stored as BLOB or CLOB columns in this XML schema.

See Also:

Appendix G, "Example Setup scripts. Oracle XML DB - Supplied XML Schemas", "xdbconfig.xsd: XML Schema for Configuring Oracle XML DB"

Defining Your Own Default Table Storage for XML Schema-Based Documents

There is an exception to this storage paradigm when storing XML schema-based XML documents. When an XML schema is registered with Oracle XML DB you can define a default storage table for each root element defined in the XML schema.

You can define your own default storage tables by adding an xdb:defaultTable attribute to the definition of the top level element When the schema is registered, Oracle XML DB establishes a link between the Repository and the default tables defined by your XML schema. You can choose to generate the default tables as part of the XML schema registration.

Your Default Table is an XMLType Table and Hierarchically Enabled

A default table is an XMLType table, that is, it is an object table based on the XMLType datatype. When an XML document, with a root element and XML schema that match your default table's root element and XML schema, is inserted into the Repository, the XML content is stored as a row in the specified default table. A resource is created that contains a reference to the appropriate row in the default table.

One of the special features of an XMLType table is that it can be hierarchically enabled. Default Tables, created as part of XML schema registration are automatically hierarchically enabled. When a table is hierarchically enabled DML operations on the default table may cause corresponding operations on the Oracle XML DB Repository. For example, when a row is deleted from the default table, any entries in the Repository which reference that row are deleted.

Example 3-31 Adding the xdb:defaultTable Attribute to the XML Schema's Element Definition

The following example shows the result of adding an xdb:defaultTable attribute to the XML schema definition's PurchaseOrder element and then registering the XML schema with the Create Table option set to TRUE:

<xs:element name="PurchaseOrder" xdb:defaultTable="XML_PURCHASEORDER">
    <xs:complexType type="PurchaseOrderType"
                    xdb:SQLType="XML_PURCHASEORDER_TYPE">
        <xs:sequence>
            <xs:element ref="Reference"/>
            <xs:element name="Actions" type="ActionsType"/>
            <xs:element name="Reject" type="RejectType" minOccurs="0"/>
            <xs:element ref="Requestor"/>
            <xs:element ref="User"/>
            <xs:element ref="CostCenter"/>
            <xs:element name="ShippingInstructions"
                        type="ShippingInstructionsType"/>
            <xs:element ref="SpecialInstructions"
                        xdb:SQLName="SPECINST"/>
            <xs:element name="LineItems" type="LineItemsType"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>                                   

SQL> begin
  2    dbms_xmlschema.registerSchema(
  3                   'http://www.oracle.com/xsd/purchaseOrder.xsd',
  4                   getDocument('purchaseOrder3.xsd'),
  5                   TRUE, TRUE, FALSE, TRUE
  6         );
  7
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL> describe XML_PURCHASEORDER

 Name                            Null?    Type
 ------------------------------- -------- ----------------------------
TABLE of SYS.XMLTYPE(XMLSchema 
http://www.oracle.com/xsd/purchaseOrder.xsd Element "PurchaseOrder") 
STORAGE Object-relational TYPE "XML_PURCHASEORDER_TYPE"

Example 3-32 Inserting an XML Document into Oracle XML DB Repository Causes a Insertion of a Row into the Table

The following example shows how, once the XML schema is registered, and the default table created, when inserting an XML document into Oracle XML DB Repository causes a row to be inserted into the designated default table:

select count(*) from XML_PURCHASEORDER;

Results in:

  COUNT(*)
 ----------
          0

-- create testFolder
declare
 result boolean;
begin
 result := dbms_xdb.createFolder('/public/testFolder');
end;
/

declare
      result boolean;
    begin
      result := dbms_xdb.createResource(
                         '/public/testFolder/purchaseOrder1.xml',
                       getDocument('purchaseOrder1.xml')
              );
    end;
/

-- PL/SQL procedure successfully completed.

commit;

-- Commit complete.

select count(*) from XML_PURCHASEORDER;

Results in:

   COUNT(*)
 ----------
          1     

Example 3-33 Deleting a Row Causes Deletion of Corresponding Entry from the Repository

This example shows when deleting a row from the hierarchy-enabled default table, the corresponding entry is deleted from the hierarchy:

select extractValue(res,'Resource/DisplayName') "Filename"
   from RESOURCE_VIEW where under_path(res,'/public/testFolder') = 1;
/

Results in:

Filename
----------------------------------------------------------------------
purchaseOrder1.xml

delete from XML_PURCHASEORDER;
1 row deleted.

SQL> commit;
Commit complete.

select extractValue(res,'Resource/DisplayName') "Filename"
   from RESOURCE_VIEW where under_path(res,'/public/testFolder') = 1
/

Results in:

no rows selected  

Accessing XML Schema-Based Content

When a resource describes XML content that has been stored in a default table the resource entry itself simply contains a reference to the appropriate row in the default table. This reference can be used to perform join operations between the resource and it's content. This can be seen in the following example.

Accessing Non-Schema-Based Content With XDBUriType

XDBUriType can be used to access the contents of a file stored in the Repository using a logical path. The following example shows how to access a resource associated with a JPEG file. The JPEG file has been inserted into the Repository. The example uses Oracle interMedia ordsys.ordimage class to extract the metadata associated with the JPEG file.

create or replace function getImageMetaData (uri varchar2)
return xmltype deterministic
is
  resType xmltype;
  resObject xdb.xdb$resource_t;
  attributes CLOB;
  xmlAttributes xmltype;
begin
   DBMS_LOB.CREATETEMPORARY(attributes, FALSE, DBMS_LOB.CALL);
   -- ordsys.ordimage.getProperties(xdburitype(uri).getBlob(),
   --                               attributes);
   select res into resType from resource_view where any_path = uri;
   resType.toObject(resObject);
   ordsys.ordimage.getProperties(resObject.XMLLOB,attributes);
   xmlAttributes := xmltype(attributes);
   DBMS_LOB.FREETEMPORARY(attributes);
   return xmlAttributes;
end;
/   

Oracle XML DB Protocol Servers

Oracle XML DB includes three protocol servers through which you can access the Repository directly from standard file-based applications.

See Also:

Chapter 19, "Using FTP, HTTP, and WebDAV Protocols"

Using FTP Protocol Server

The FTP Protocol Server allows standard FTP clients to access content stored in the Repository as if it were content behind a regular FTP server. FTP Protocol Server works with standard FTP clients, including:

Figure 3-6, Figure 3-7, Figure 3-8, and Figure 3-9 show examples of how you can access the root level of the Repository using various of standard FTP clients.

Figure 3-6 Accessing the Repository Root Level from the DOS Command Prompt Command Line

Text description of 3_a_commpr.gif follows
Text description of the illustration 3_a_commpr.gif


Figure 3-7 Accessing the Repository Root Level fro m IE Browser Web Folder Menu

Text description of 3_b_webfldr.gif follows
Text description of the illustration 3_b_webfldr.gif


Figure 3-8 Accessing the Repository Root Level fro m WS_FTP95LE FTP Interface Program

Text description of 3_c_ftp.gif follows
Text description of the illustration 3_c_ftp.gif


Figure 3-9 Accessing the Repository Root Level from a Telnet Session

Text description of 3_d_telnet.gif follows
Text description of the illustration 3_d_telnet.gif


Using HTTP/WebDAV Protocol Server

Oracle XML DB Repository can also be accessed using HTTP and WebDAV. WebDAV support allows applications such as a Microsoft's Web Folders client, Microsoft Office, and Macromedia's Dreamweaver to directly access Oracle XML DB Repository. Figure 3-10 and Figure 3-11 are examples of using HTTP and WebDAV to access the Repository.

Figure 3-10 Accessing the Repository Using HTTP/WebDAV from Microsoft Windows Explorer

Text description of 3_e_explor.gif follows
Text description of the illustration 3_e_explor.gif


Figure 3-11 Accessing the Repository Using HTTP/WebDAV Protocol Server from Microsoft Web Folders Client

Text description of 3_f_http.gif follows
Text description of the illustration 3_f_http.gif


By providing support for standard industry protocols, Oracle XML DB makes it possible to upload and access data and documents stored in Oracle9i database using standard, familiar interfaces.