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
XMLType
i 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>