XML w Oracle9i
autor: leopold wegner
Coś o XML
XML (eXtensible Markup Language) standard opracowany przez W3C
standard opisu strukturalnych danych
odzielenie danych od struktury i prezentacji (do opisu prezentacji służy XSL (eXtensible Stylesheet Language)
Komponenty XML w Oracle9i
XMLType- nowy typ danych do przechowywania dokumentów XML, obsługa zapytańSYS_XMLGEN- funkcja SQL do tworzenia dokumnetów XMLSYS_XMLAGG- funkcja SQL do łączenia wielu dokumentów XMLDBMS_XMLGEN- wbudowany pakiet do tworzenia dokumnetów XML z zapytań SQL- wsparcie URI - przechowywanie i odzyskiwanie globalnych i wewnątrz bazodanowych referencji
- wsparcie Oracle Text (interMedia Text) - wsparcie XPath dla
XMLTypei kolumn tekstowych
- XML Parser for Java and XSLT Processor
- XML Schema Processor for Java
- XML Class Generator for Java
- XSQL Servlet and Pages
- XML SQL Utility (XSU) for Java
- XML Transviewer Beans
- DOMBuilder Bean
- XSLTransformer Bean
- DBAccessBean
- TreeViewer Bean
- SourceViewer Bean
- XMLTransformPanel Bean
- DBViewer Bean
- XML Parser for C
- XML Schema Processor for C
- XML Parser for C++
- XML Schema Processor for C++
- XML Class Generator for C++
- XML Parser for PL/SQL
- XML SQL Utility (XSU) for PL/SQL
Typowe zastosowania komponentów XML w rozwiązaniach biznesowych

XSQL Servlet and Pages, Oracle9i Internet File System (9iFS), JDeveloper, Business Components for Java (BC4J), Oracle Portal (WebDB), Oracle9iAS Reports Services, and Oracle9i Dynamic Services - kolejne komponenty mogące się przydać podaczas tworznia aplikacji XML-owej.
CONTAINS i WITHIN)
XMLType
(implementacja poprzez CLOB - Character Large Object)
lub też po prostu kolumny CLOB/BLOB; wykorzystanie w przypadku XMLType
funkcji Extract() i ExistsNode()
lub indeksowania Oracle Text do przeszukiwania takich dokumentówXMLType
XMLType przechowuje dokumenty XML
jako Character Large Objects (CLOBs). Indeksowanie Oracle Text (interMedia
Text) może być użyte do obsługi kolumny XMLType, a
także zapytań wykorzystujących operator CONTAINS lub
Xpath-podobnej składni. Typ XMLType posiada wiele funkcji, które
mogą zostać użyte do pracy z fragmentami dokumentu XML.

Kiedy będzie potrzeba wyciągnięcia danych z bazy, korzystamy z perspektywy, która bazując na różnych kawałkach danych zwróci posklejany wynik. Następnie XML SQL Utility stworzy całościowy dokument XML.
Coś na temat komponentów
Działanie parsera XML dla Javy

Przykładowe zastosowanie parsera XML i DOM (dla Javy)
// This file demonstates a simple use of the parser and DOM API.
// The XML file given to the application is parsed.
// The elements and attributes in the document are printed.
// This demonstrates setting the parser options.
//
import java.io.*;
import java.net.*;
import org.w3c.dom.*;
import org.w3c.dom.Node;
import oracle.xml.parser.v2.*;
public class DOMSample
{
static public void main(String[] argv)
{
try
{
if (argv.length != 1)
{
// Must pass in the name of the XML file.
System.err.println("Usage: java DOMSample filename");
System.exit(1);
}
// Get an instance of the parser
DOMParser parser = new DOMParser();
// Generate a URL from the filename.
URL url = createURL(argv[0]);
// Set various parser options: validation on,
// warnings shown, error stream set to stderr.
parser.setErrorStream(System.err);
parser.setValidationMode(DTD_validation);
parser.showWarnings(true);
// Parse the document.
parser.parse(url);
// Obtain the document.
XMLDocument doc = parser.getDocument();
// Print document elements
System.out.print("The elements are: ");
printElements(doc);
// Print document element attributes
System.out.println("The attributes of each element are: ");
printElementAttributes(doc);
parser.reset();
}
catch (Exception e)
{
System.out.println(e.toString());
}
}
static void printElements(Document doc)
{
NodeList nl = doc.getElementsByTagName("*");
Node n;
for (int i=0; i<nl.getLength(); i++)
{
n = nl.item(i);
System.out.print(n.getNodeName() + " ");
}
System.out.println();
}
static void printElementAttributes(Document doc)
{
NodeList nl = doc.getElementsByTagName("*");
Element e;
Node n;
NamedNodeMap nnm;
String attrname;
String attrval;
int i, len;
len = nl.getLength();
for (int j=0; j < len; j++)
{
e = (Element)nl.item(j);
System.out.println(e.getTagName() + ":");
nnm = e.getAttributes();
if (nnm != null)
{
for (i=0; i<nnm.getLength(); i++)
{
n = nnm.item(i);
attrname = n.getNodeName();
attrval = n.getNodeValue();
System.out.print(" " + attrname + " = " + attrval);
}
}
System.out.println();
}
}
static URL createURL(String fileName)
{
URL url = null;
try
{
url = new URL(fileName);
}
catch (MalformedURLException ex)
{
File f = new File(fileName);
try
{
String path = f.getAbsolutePath();
String fs = System.getProperty("file.separator");
if (fs.length() == 1)
{
char sep = fs.charAt(0);
if (sep != '/')
path = path.replace(sep, '/');
if (path.charAt(0) != '/')
path = '/' + path;
}
path = "file://" + path;
url = new URL(path);
}
catch (MalformedURLException e)
{
System.out.println("Cannot create url for: " + fileName);
System.exit(0);
}
}
return url;
}
}
XML Class Generator
XML Class Generator tworzy zbiór klas Java lub C++ na podstawie dokumentów DTD, XML Schema.

XML Transviewer Java Beans
XML Transviewer Beans to zbiór komponentów XML dla aplikacji i apletów Javy. Służą do przekształacania i przeglądania danych i dokumentów XML. Komponenty mogą być zintegrowane z Oracle JDeveloper.
zawiera Java XML Parser razem z bean interfejsem (rozszerzona funkcjonalność umożliwiając parsowanie asynchroniczne). Aplikacja w Javie może parsować kolejno wiele dokumentów zwracając natychmiast sygnały kontrole wywołującemu.
ułatwia przeglądanie plików XML i XSL (kolorowanie składni). Łatwo zintegrować z DOM Builder Bean, co umożliwia pre i post parsowanie oraz sprawdzanie poprawności względem danego DTD.
wizualizuje drzewo opisujšce dokument XML, umożliwiając wygodne przeglądanie (zwijanie gałęzi) i modyfikowanie tego drzewa
umożliwia translację dokumentu XML do innych formatów, np. HTML, DDL, poprzez zastosowanie szablonu styli XSL. W połączniu z innymi komponentami, XSL TB pozwala aplikacji lub użytkownikowi na natychmiastowe skontrolowanie wyniku tłumaczenia. Inne zastosowanie - w aplikacji po stronie serwera albo w serwlecie do przekształcania dokumentu XML (np. wynik zapytania) w HTML (wyświetlenie przez przeglądarkę).
Ten komponent używa innch ziaren do tworzenia przykładowych aplikacji, które mogą przetwarzać pliki XML. Zapewnia interfejs do ładowania dokumentów XML i XSL. Używa:
- Visual beans do przeglądania i edycji plików
- Transformer bean do zastosowania arkuszy stylów do dokumentu XML (podgląd wyniku)
XML SQL Utility (XSU)
XML SQL Utility - klasy Javy do automatycznego i dynamicznego przetwarzania wyników zapytań SQL w dokumenty XML. Mogą być używane do:Struktura wynikowego dokumentu XML jest oparta na wewnętrznej strukturze schematu bazy danych (którego dotyczyło zapytanie).
Przykładowy wynik działania XSU:
CREATE TYPE AddressType AS OBJECT (
STREET VARCHAR2(20),
CITY VARCHAR2(20),
STATE CHAR(2),
ZIP VARCHAR2(10)
);
CREATE TYPE EmployeeType AS OBJECT ( EMPNO NUMBER, ENAME VARCHAR2(20), SALARY NUMBER, EMPADDR AddressType );
CREATE TYPE EmployeeListType AS TABLE OF EmployeeType;
CREATE TABLE dept ( DEPTNO NUMBER, DEPTNAME VARCHAR2(20), DEPTADDR AddressType, EMPLIST EmployeeListType ) NESTED TABLE EMPLIST STORE AS EMPLIST_TABLE;
<?xml version='1.0'?>
<ROWSET>
<ROW num="1">
<DEPTNO>100</DEPTNO>
<DEPTNAME>Sports</DEPTNAME>
<DEPTADDR>
<STREET>100 Redwood Shores Pkwy</STREET>
<CITY>Redwood Shores</CITY>
<STATE>CA</STATE>
<ZIP>94065</ZIP>
</DEPTADDR>
<EMPLIST>
<EMPLIST_ITEM num="1">
<EMPNO>7369</EMPNO>
<ENAME>John</ENAME>
<SALARY>10000</SALARY>
<EMPADDR>
<STREET>300 Embarcadero</STREET>
<CITY>Palo Alto</CITY>
<STATE>CA</STATE>
<ZIP>94056</ZIP>
</EMPADDR>
</EMPLIST_ITEM>
<!-- additional employee types within the employee list -->
</EMPLIST>
</ROW>
<!-- additional rows ... -->
</ROWSET>
Przykład kody Javy:
Import oracle.jdbc.driver.*;
import oracle.xml.sql.query.OracleXMLQuery;
import java.lang.*;
import java.sql.*;
// class to test the String generation!
class testXMLSQL {
public static void main(String[] argv)
{
try{
// create the connection
Connection conn = getConnection("scott","tiger");
// Create the query class.
OracleXMLQuery qry = new OracleXMLQuery(conn, "select * from emp");
// Get the XML string
String str = qry.getXMLString();
// Print the XML output
System.out.println(" The XML output is:\n"+str);
// Always close the query to get rid of any resources..
qry.close();
}catch(SQLException e){
System.out.println(e.toString());
}
}
// Get the connection given the user name and password..!
private static Connection getConnection(String username, String password)
throws SQLException
{
// register the JDBC driver..
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// Create the connection using the OCI8 driver
Connection conn =
DriverManager.getConnection("jdbc:oracle:oci8:@",username,password);
return conn;
}
}
XSQL Page Processor and Servlet
The XSQL Page Processor and Servlet - narzędzie do przetwarzania zapytań SQL i zwracania rezultatów w postaci XML, zaimplementowane jako serwlet Javy. Zastosowanie: dostarczanie dynamicznej zawartości stron internetowych. Na wejściu dostaje plik XML zawierający zapytania SQL. Korzysta z parsera XML i XSU oraz XLST. Można uruchomić ten serwlet na każdym serwerze webowym, który wspiera serwlety Javy.
XSQL Page Processor and Servlet w działaniu:

Przykładowe użycie XDK
Generacja dokumentów XML używająć XDK dla Java

Generacja dokumentów XML używająć XDK dla C++ (dla C bez Class generatora)

Generacja dokumentów XML używająć XDK dla PL/SQL

TYP XMLType
proste przykłądy z użyciem XMLType
CREATE TABLE warehouses(
warehouse_id NUMBER(3),
warehouse_spec SYS.XMLTYPE,
warehouse_name VARCHAR2(35),
location_id NUMBER(4));
INSERT into warehouses (warehouse_id, warehouse_spec) VALUES (1001, sys.XMLType.createXML( '<Warehouse whNo="100"> <Building>Owned</Building> </Warehouse>'));
SELECT w.warehouse_spec.extract('/Warehouse/Building/text()').getStringVal()
"Building"
FROM warehouses w
Building
-----------------
Owned
UPDATE warehouses SET warehouse_spec = sys.XMLType.createXML('<Warehouse whono="200"> <Building>Leased</Building></Warehouse>'));
DELETE FROM warehouses e WHERE e.warehouse_spec.extract('//Building/text()').getStringVal() = 'Leased';
CREATE TABLE po_xml_tab(
poid number,
poDoc SYS.XMLTYPE);
ALTER TABLE po_xml_tab add (custDoc sys.XMLType); ALTER TABLE po_xml_tab drop (custDoc sys.XMLType);CREATE TABLE po_xml_tab( poid NUMBER(10), poDoc SYS.XMLTYPE ) XMLType COLUMN poDoc STORE AS CLOB ( TABLESPACE lob_seg_ts STORAGE (INITIAL 4096 NEXT 4096) CHUNK 4096 NOCACHE LOGGING );
przykłądy zapytań
<PO>
<PONO>100</PONO>
<PNAME>Po_1</PNAME>
<CUSTOMER CUSTNAME="John"/>
<SHIPADDR>
<STREET>1033, Main Street</STREET>
<CITY>Sunnyvalue</CITY>
<STATE>CA</STATE>
</SHIPADDR>
</PO>
Kilka konstrukcji używanych w XPath
"/" oznacza korzeń drzewa wyżenia XPath np. /PO odpowiada dziecku korzenia o nazwie "PO"
"/" oznacza również separator do identyfikacji dzieci poszczególnych węzłów np. /PO/PNAME
"//" oznacza wszystkich potomków aktualnego węzła np. PO//ZIP odpowiada każdemu elementowi zip, który jest pod elementem o nazwie "PO"
"*" oznacza dowolny węzeł np. /PO/*/STREET odpowiada każdemu elementowi STREET, który jest wnukiem elementu o nazwie "PO"
INSERT INTO po_xml_tab values (100, sys.xmltype.createxml('<?xml version="1.0"?> <PO> <PONO>221</PONO> <PNAME>PO_2</PNAME> </PO>')); INSERT INTO po_xml_tab values (200, sys.xmltype.createxml('<?xml version="1.0"?> <PO> <PONAME>PO_1</PONAME> </PO>')); SELECT e.poDoc.extract('//PONO/text()').getNumberVal() as pono FROM po_xml_tab e WHERE e.podoc.existsnode('/PO/PONO') = 1 AND e.poid > 1; declare poxml SYS.XMLType; cust SYS.XMLType; val VARCHAR2; begin -- select the adt instance select poDoc into poxml from po_xml_tab p where p.poid = 100; -- do some traversals and print the output cust := poxml.extract('//SHIPADDR'); -- do something with the customer XML fragment val := cust.getStringVal(); dbms_output.put_line(' The customer XML value is '|| val); end;
CREATE TABLE cust_tab ( custid number primary key, custname varchar2(20) ); insert into cust_tab values (1001, "John Nike"); CREATE table po_rel_tab ( pono number, pname varchar2(100), custid number refernces cust_tab shipstreet varchar2(100), shipcity varchar2(30), shipzip varchar2(20) ); <?xml version = '1.0'?> <PO> <PONO>2001</PONO> <CUSTOMER CUSTNAME="John Nike"/> <SHIPADDR> <STREET>323 College Drive</STREET> <CITY>Edison</CITY> <STATE>NJ</STATE> <ZIP>08820</ZIP> </SHIPADDR> </PO> insert into po_rel_tab as select p.poDoc.extract('/PO/PONO/text()').getnumberval(), p.poDoc.extract('/PO/PNAME/text()').getstringval(), -- get the customer id corresponding to the customer name ( SELECT custid FROM cust_tab c WHERE c.custname = p.poDoc.extract('/PO/CUSTOMER/@CUSTNAME').getstringval() ), p.poDoc.extract('/PO/SHIPADDR/STREET/text()').getstringval(), p.poDoc.extract('//CITY/text()').getstringval(), p.poDoc.extract('//ZIP/text()').getstringval(), from po_xml_tab p;PONO PNAME CUSTID SHIPSTREET SHIPCITY SHIPZIP ---------------------------------------------------------------- 2001 1001 323 College Drive Edison 08820
przykłąd zastosowania DBMS_XMLGEN
CREATE TABLE new_departments ( department_id NUMBER PRIMARY KEY, department_name VARCHAR2(20) ); CREATE TABLE new_employees ( employee_id NUMBER PRIMARY KEY, last_name VARCHAR2(20), department_id NUMBER REFERENCES departments ); CREATE TYPE emp_t AS OBJECT( "@employee_id" NUMBER, last_name VARCHAR2(20) ); CREATE TYPE emplist_t AS TABLE OF emp_t; CREATE TYPE dept_t AS OBJECT( "@department_id" NUMBER, department_name VARCHAR2(20), emplist emplist_t ); qryCtx := dbms_xmlgen.newContext ('SELECT dept_t(department_id, department_name, CAST(MULTISET (SELECT e.employee_id, e.last_name FROM employees e WHERE e.department_id = d.department_id) AS emplist_t)) AS deptxml FROM departments d'); DBMS_XMLGEN.setRowTag(qryCtx, NULL);<ROWSET> <DEPTXML DEPARTMENT_ID="10"> <DEPARTMENT_NAME>SALES</DEPARTMENT_NAME> <EMPLIST> <EMP_T EMPLOYEE_ID="30"> <LAST_NAME>Scott</LAST_NAME> </EMP_T> <EMP_T EMPLOYEE_ID="31"> <LAST_NAME>Mary</LAST_NAME> </EMP_T> </EMPLIST> </DEPTXML> <DEPTXML DEPARTMENT_ID="20"> ... </ROWSET>