![]() |
Note :
Before installing XSQL Pages on a production server, please read the section below on Security Considerations for Production XSQL Pages System |
SQL is the standard you are already familiar with for accessing appropriate views of business information in your production systems. XML provides an industry-standard, platform-neutral format for representing the results of SQL queries as "datagrams" for exchange, and XSLT defines the industry-standard way to transform XML "datagrams" into target XML, HTML, or Text formats as needed.
By combining the power of SQL, XML, and XSLT in the server with the ubiquitously available HTTP protocol for the transport mechanism you can:
Query an appropriate logical "view" of business data needed by the request,
Return the "datagram" in XML over the web to the requester, or optionally
Transform the information flexibly into any XML, HTML, or text format they require.
Transform the "datapage" to produce a final result in any desired XML, HTML, or Text-based format using an associated XSLT Transformation.
Keep the "datapage" cleanly separate from the way that data will be rendered to the requester.
For example, to serve a list of available flights today for any desired destination city from your enterprise database in response to a URL request like:
http://yourcompany.com/AvailableFlightsToday.xsql?City=NYCyou might write an XSQL Page like:
<?xml version="1.0"?> <xsql:query connection="demo" bind-params="City" xmlns:xsql="urn:oracle-xsql"> SELECT Carrier, FlightNumber, Origin, TO_CHAR(ExpectedTime,'HH24:MI') Due FROM FlightSchedule WHERE TRUNC(ArrivalTime) = TRUNC(SYSDATE) AND Destination = ? ORDER BY ExpectedTime </xsql:query>To return the same information in HTML or some alternative XML format that might comply with a particular DTD you've been given, just associate an appropriate with
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="FlightList.xsl"?> <xsql:query connection="demo" bind-params="City" xmlns:xsql="urn:oracle-xsql"> SELECT Carrier, FlightNumber, Origin, TO_CHAR(ExpectedTime,'HH24:MI') Due FROM FlightSchedule WHERE TRUNC(ArrivalTime) = TRUNC(SYSDATE) AND Destination = ? ORDER BY ExpectedTime </xsql:query>Once you've built a set of XSQL Pages, you can "exercise" your templates by:
Using the Oracle XSQL Command Line Utility in batch programs,
Calling the
Using XSQL Pages, the information you already have in your Oracle database,
and the power of SQL, XML, and XSLT, you'll quickly discover that a powerful
and flexible world of web data publishing is at your fingertips.
New behavior introduced for parameters, session parameters, or cookies that have names which do not make legal XML names. Instead of generating an element <paramName> paramValue </paramName>, it will now generate an element named <xsql-illegal-name name="paramNameWithIllegalChars">paramValues</xsql-illegal-name>
XSQL-018: NullPointer starting up stylesheet pool under load (Bug# 2661849)
When a user modified the default seting of 1 initial stylesheet in the pool, say putting 50, and then: (1) Restarts the servlet container or (2) Sends multiple, simultaneous requests to the XSQL page engine, then while the first thread to come in is initializing the sylesheet, another thread can sneak in and end up getting a null pointer exception while the other is still working to flesh out the pool instances.
<xsql:insert-param> Continues Incorrectly On Parse Failure
If the XML document posted in a request parameter was ill-formed, the processing of the insert incorrectly continued. Now a parse error stops processing as it should.
<xsql:include-xsql reparse="yes"> Fails if Document Refers to DTD
If the XML document posted in a request parameter was ill-formed, the processing of the insert incorrectly continued. Now a parse error stops processing as it should.
XSQL Connection Pools Not Cleaned Up When Servlet Destroyed
Some web servers allow the server administrator to shut down servlets
and restart them without ever shutting down the Java VM that is running
them. Under this scenario, the XSQL connection pool connections were not
being cleaned up correctly. Now, when the servlet container calls
Servlet Continues Incorrectly After Reporting Error with XSQLConfig.xml
If the XSQLConfig.xml file is malformed or cannot be found, the XSQL Servlet reported a helpful error reporting this problem, but then incorrectly continued handling requests as if it had read a valid config file. This could lead to NullPointerException errors if database connections
XML Insert Demo Inserts Data with Leading/Trailing Spaces
The Insert XML Demo web page inadvertently contained leading and trailing spaces around the sample XML data to be inserted. These spaces have been removed.
Page, Session Parameters with Multibyte Values Handled Incorrectly
Prior to this fix, an attempt to assign a multibyte value to a page-private parameter or a session parameter resulted in the value being handled incorrectly. HTTP request parameters with multibyte values worked correctly before.
![]() |
Note :
Since HTTP header entries are govered by the RFC822 standard (http://www.faqs.org/rfcs/rfc822.html, Section 3.2) that restricts headers to characters in the ISO 8859-1 character set, setting HTTP cookies to multibyte values is not guaranteed to work correctly. |
Null Pointer Exception Using Tomcat When Relative URL Differs by Case
When running XSQL Pages using the Apache Tomcat servlet engine, an XSQL
page that refers to an XSL stylesheet with a name like
Actions Removed by User-Written Action Handlers Still Executed
Prior to this fix, if a user-written action handler removed nodes from
the XSQL page (typically ones nested inside the
Custom Action Handlers Cannot Be Found in a Different JAR file on OC4J
Prior to this fix, if you are using Oracle9iAS OC4J to run XSQL pages, under certain circumstances the server would fail to find your action handler classes. Now the classes are found correctly with OC4J in all cases.
Illegal State Exception Posting XML to XSQL Page on OC4J
Prior to this fix, if you were posting an XML document to an XSQL page running under Oracle9iAS OC4J, an Illegal State Exception may result. This error no longer occurs.
The implementation of the built-in
<XSQLConfig> <processor> : <!-- | Sets the default OWA Page Buffer fetch style | used by the <xsql:include-owa> action | Valid values are CLOB or TABLE. | | If set to CLOB, the processor uses temporary | CLOB to retrieve the OWA page buffer. | | If set to TABLE the processor uses a more | efficient approach that requires the existence | of the Oracle user-defined type named | XSQL_OWA_ARRAY defined using the DDL statement: | | CREATE TYPE xsql_owa_array AS TABLE OF VARCHAR2(32767) | +--> <owa> <fetch-style>TABLE</fetch-style> </owa> </processor> </XSQLConfig>Create the
CREATE TYPE xsql_owa_array AS TABLE OF VARCHAR2(32767);
![]() |
Note :
If the default OWA fetch style is set to |
The value of the xpath attribute can be any valid XPath expression,
optionally built using XSQL parameters as part of the attribute value like
any other XSQL action element. Once a page-private parameter is set, subsequent
action handlers can use this value as a lexical parameter (
<xsql:set-page-param> Now Supports xpath="Expr" Attribute
It is now possible to set the value of a page-private parameter to the value of an XPath expression, evaluated against an XML document or HTML form that has been posted to the XSQL Page Processor. The syntax is:
<xsql:set-page-param name="po_id" xpath="/technology/PurchaseOrder/Id"/>The value of the xpath attribute can be any valid XPath expression, optionally built using XSQL parameters as part of the attribute value like any other XSQL action element. Once a page-private parameter is set, subsequent action handlers can use this value as a lexical parameter (
New Airport SOAP Service Demo
A variant on the existing Airport code lookup demo is provided that illustrates how you can use XSQL pages to create SOAP-based Web Services. The demo uses the new feature above to select XPath expressions out of the posted XML, and uses an XSLT stylesheet to format the response in the appropriate SOAP encoding.
![]() |
Note :
You will need to edit the |
Simplified Inclusion of XML from CLOB's and VARCHAR2 Columns
The existing
<xsql:include-xml bind-params="id"> select x.document.contents from xmldoc x where docid = ? </xsql:include-xml>When the action element has a SQL statement in its content, then a connection is required on the page. Only a single row is fetched from the SQL query, and the value of the first column in the result is retrieved and parsed. Both CLOB-valued and VARCHAR2-valued columns or SQL expressions are supported.
The existing functionality of
<xsql:include-xml href="someUrl"/>New <xsql:include-posted-xml> Action to Include Posted XML
You can use the new
<xsql:include-posted-xml/>Support for Apache FOP 0.18 Release
The XSQL FOP Serializer, for producing PDF output from XSQL pages, has been tested with release 0.18.1 of Apache FOP. Due to an API change in the Apache FOP code, this release can only work with the 0.16 FOP release or greater, but not with earlier releases.
![]() |
Note :
The implementation of the |
New Online Documentation for XSQL
The XSQL chapter in the "Oracle 9i Application Developer's Guide - XML" has been dramatically improved to feature all of the reference and tutorial material that formerly was only the these release notes. This rewritten chapter, entitled "XSQL Pages Publishing Framework", appears on Oracle Technet as part of the Oracle9i documentation set.
Support for Apache FOP 0.19.0
If you need to render PDF output from XSQL pages, this release supports and requires working with the 0.19.0 release of Apache FOP. The source code for the FOP Serializer looks like this:
package oracle.xml.xsql.serializers;
import org.w3c.dom.Document;
import java.io.PrintWriter;
import oracle.xml.xsql.*;
import org.apache.fop.messaging.MessageHandler;
import org.apache.fop.apps.*;
import java.io.*;
// ----------------------------------
// Tested with the FOP 0.19.0 Release
// ----------------------------------
public class XSQLFOPSerializer implements XSQLDocumentSerializer {
private static final String PDFMIME = "application/pdf";
public void serialize(Document doc, XSQLPageRequest env) throws Throwable {
try {
// First make sure we can load the driver
Driver FOPDriver = new Driver();
// Then set the content type before getting the reader/
env.setContentType(PDFMIME);
// Tell FOP not to spit out any messages.
MessageHandler.setOutputMethod(MessageHandler.NONE);
FOPDriver.setupDefaultMappings();
FOPDriver.buildFOTree(doc);
FOPDriver.setOutputStream(env.getOutputStream());
FOPDriver.setRenderer(FOPDriver.RENDER_PDF);
FOPDriver.format();
FOPDriver.render();
}
catch (Exception e) {
// Cannot write PDF output for the error anyway.
// So maybe this stack trace will be useful info
e.printStackTrace(System.err);
}
}
}
![]() |
Note :
This release of Oracle XSQL Pages, release 9.0.2B, only works with Apache FOP release 0.19.0 or higher. |
Deploy XSQL as Global Application to Oracle9iAS OC4J Servlet Container
You can now deploy the Oracle XSQL Pages framework to the Oracle9iAS OC4J Servlet Container as a global application. The installation steps are documented in the Installation section below.
Immediately Read Values Set as Cookies
Typically, cookies set as part of the current HTTP request are not "visible"
to your application until the next time the browser makes a request. This
is because new cookies are set as part of the HTTP response, while existing
cookies are read from the HTTP request. To simplify the XSQL programming
experience using cookies, you can now add the additional (optional) attribute
Set Multiple Parameter Values with a Single SQL Statement
As a new alternative to their existing
<xsql:set-page-param names="fullname securitylevel last_visit" bind-params="username password"> select first_name||' '||last_name, auth_level, to_char(last_visit,'DD/MM/YYYY') from site_user_table where username = ? and password = ? </xsql:set-page-param>This will set the values of the
Several Demos Updated to Use New Features
The
The
Failure to follow this recommendation could mean that a user of your site could accidentally (or intentionally) browse the contents of your configuration file.
Disable Default Client Stylesheet Overrideability When Your Pages Go Production
By default, the XSQL Page Processor allows the user to supply a stylesheet
in the request by passing a value for the special
Be Alert of the Use of Subsitution Parameters
With power comes responsibility. Any product, like Oracle Reports and XSQL Pages among others, that supports the use of lexical substitution variables in a SQL query can give a developer enough rope to hang himself. Any time you deploy an XSQL page that allows important parts of a SQL statement (or at the extreme, the entire SQL statement) to be substituted by a lexical parameter, you should make sure that you have taken appropriate precautions against misuse.
For example, one of the demonstrations that comes with XSQL Pages is
the "adhoc query demo". It illustrates how the entire SQL statement of
an
Techniques that can be used to make sure your pages are not abused include:
Using true bind variables instead of lexical bind variables when substituting single values in a SELECT statement. If you need to make syntactic parts of your SQL statement parameterized, then lexical parameters are the only game in town. Otherwise, true bind variabled are recommended so that any attempt to pass an invalid value will generate an error instead of producing an unexpected result.
http://yourmachine/xsql/index.html
![]() |
| Action Element | Description |
| Set the value of a top-level XSLT stylesheet parameter. | |
| Set a page-level (local) parameter that can be referred to in subsequent SQL statements in the page. | |
| Set an HTTP-Session level parameter. | |
| Set an HTTP Cookie. | |
| Execute an arbitrary SQL statement and include its result set in canonical XML format. | |
| Includes the canonical XML representation of the result set of a cursor returned by a PL/SQL stored function. | |
| Include a parameter and its value as an element in your XSQL page. | |
| Include all request parameters as XML elements in your XSQL page. | |
| Include arbitrary XML resources at any point in your page by relative or absolute URL. | |
| Include the results of executing a stored procedure that makes use of the Oracle Web Agent (OWA) packages inside the database to generate XML. | |
| Include the results of one XSQL page at any point inside another. | |
| Insert the XML document (or HTML form) posted in the request into a database table or view. | |
| Update an existing row in the database based on the posted XML document supplied in the request. | |
| Delete an existing row in the database based on the posted XML document supplied in the request. | |
| Inserts the XML document contained in the value of a single parameter. | |
| Execute a SQL DML statement or PL/SQL anonymous block. | |
| Invoke a user-defined action handler, implemented in Java, for executing custom logic and including custom XML information into your XSQL page. |
HTTP Cookies
HTTP Session Variables
Local XSQL Page Parameters
<xsql:query>
select name from users where userid = {@myParam}
</xsql:query>
or in the attribute value of an XSQL Action Element, like:
<xsql:query max-rows="{@myParam}">
:
</xsql:query>
the XSQL Page Processor determines the value of the parameter by using
the following logic.
If the request is being processed by the XSQL Servlet, then check
in the following order if
An HTTP Cookie
An HTTP Session Variable
An HTTP Request Parameter
An XSQL Request parameter
Provided on the command-line or passed into the
Using the
When using the Apache JServ servlet engine, the use of relative stylesheet
and XSQL page references may not produce the results you expect if you
have an elaborate virtual path mapping. Since the Apache JServ engine does
not properly implement the Servlet API method
JDK 1.2.2
JDK 1.3
![]() |
Note :
Numerous users have reported problems using XSQL Pages and the XSQL Servlet with JDK 1.1.7 which suffers problems in its character set conversion routines for UTF-8 that make it unusable for processing XSQL Pages. |
Oracle9iAS OC4J Servlet Engine
Allaire JRun 2.3.3 and 3.0.0
Apache 1.3.9 with JServ 1.0 and 1.1
Apache 1.3.9 with Tomcat 3.1 or 3.2 Servlet Engine
Apache Tomcat 3.1 or 3.2 Web Server + Servlet Engine
Caucho Resin 1.1
Java Web Server 2.0
Weblogic 5.1 Web Server
NewAtlanta ServletExec 2.2 and 3.0 for IIS/PWS 4.0
Oracle8i Lite Web-to-Go Server
Oracle8i 8.1.7 Oracle Servlet Engine
Sun JavaServer Web Development Kit (JSWDK) 1.0.1 Web Server
Oracle9iAS OC4J Servlet Engine
Apache 1.3.9 with Tomcat 3.1 or 3.2 Servlet Engine
Apache Tomcat 3.1 or 3.2 Web Server + Tomcat 3.1 or 3.2 Servlet Engine
Caucho Resin 1.1 (Built-in JSP 1.0 Support)
NewAtlanta ServletExec 2.2 and 3.0 for IIS/PWS 4.0 (Built-in JSP 1.0 Support)
Oracle8i Lite Web-to-Go Server with Oracle JSP 1.0
Oracle8i 8.1.7 Oracle Servlet Engine
Any Servlet Engine with Servlet API 2.1+ and Oracle JSP 1.0
Oracle8i 8.1.6 Driver for JDBC 1.x
Oracle8i 8.1.7 Driver for JDBC 1.x
Oracle8i Lite 4.0 Driver for JDBC 1.x
Oracle8i 8.1.6 Driver for JDBC 2.0
Oracle8i 8.1.7 Driver for JDBC 2.0
Oracle9i 9.0.1 Driver for JDBC 2.0
Oracle XML SQL Utilities for Java, version 2.0.1 or higher
A Web Server that supports Java Servlets
A JDBC driver, like Oracle JDBC or Oracle8i Lite JDBC
Oracle XML SQL Utility,
Clicking on the 'Software' icon at the top of the page:
![]() |
Logging in with your OTN username and password (registration is free if you do not already have an account).
Selecting whether you want the NT or Unix download (both contain the same files)
Acknowledging the licensing agreement and download survey
Clicking on appropriate
Change directory to
tar xvfz xdk_xxx.tar.gzon Unix, or on Windows:
pkzip25 -extract -directories xdk_xxx.zipusing the pkzip25 command-line tool or the WinZip visual archive extraction tool.
<?xml version="1.0" ?> <XSQLConfig> : <connectiondefs> <connection name="demo"> <username>scott</username> <password>tiger</password> <dburl>jdbc:oracle:thin:@localhost:1521:ORCL</dburl> <driver>oracle.jdbc.driver.OracleDriver</driver> </connection> <connection name="lite"> <username>system</username> <password>manager</password> <dburl>jdbc:Polite:POlite</dburl> <driver>oracle.lite.poljdbc.POLJDBCDriver</driver> </connection> </connectiondefs> : </XSQLConfig>
or the JAR file for the JDBC driver you will be using instead
![]() |
Note :
In a production system, make sure your |
Map the
Map a virtual directory
You can install the XSQL Servlet as a global application to handle
Deploy the ear file with the command (all on one line, replacing admin and welcome with your username and password for OC4J administration):
java -jar admin.jar ormi://yourserver/ admin welcome -deploy -file XDKHome/xdk/demo/java/xsql/xsqldemos.ear -deploymentName xsqldemosBind the web application with the command (all on one line, replace admin and welcome as above, using
java -jar admin.jar ormi://yourserver/ admin welcome -bindWebApp xsqldemos xsqldemos http-web-site /xsqlThe demos can then be run by browsing:
To install XSQL Servlet in the Oracle9iAS OC4J servlet container as
a global application, do the following instead. Assuming your OC4J installation
home is
Edit the
<orion-web-app ...etc... > : etc : <web-app> <servlet> <servlet-name>xsql</servlet-name> <servlet-class>oracle.xml.xsql.XSQLServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xsql</servlet-name> <url-pattern>/*.xsql</url-pattern> </servlet-mapping> : etc : </web-app> </web-app>At this point, you can refer to any XSQL page in any virtual path and it will be processed by the XSQL Servlet. If you want to try the XSQL built-in samples, demos, and online help then you need to perform the following additional step to map a virtual path of
Edit the
<orion-web-app ...etc...> : etc : <virtual-directory virtual-path="/technology/xsql" real-path="/technology/c:/xdk/xdk/demo/java/xsql/" /> : etc : </orion-web-app>
![]() |
Note :
In a production system, make sure your |
![]() |
Note :
In a production system, make sure your |
This is done by starting the JRun Administrator, clicking on the General
tab, and clicking on the Java subtab as shown below.
![]() |
Append the list of JAR files and directory that need to be in the server
CLASSPATH for the XSQL Servlet to the existing value in the Java Classpath
field. Assuming you installed into
C:\xsql\lib\xsu111.jar; C:\xsql\lib\xmlparserv2.jar; directory_where_JDBC_Driver_resides\classes111.zip; C:\xsql\lib\oraclexsql.jar; directory_where_XSQLConfig.xml_residesTo use Apache FOP for PDF Generation, you need to add:
C:\xsql\lib\xsqlserializers.jar; FOPHOME/fop.jar; FOPHOME/lib/batik.jarTo use the Oracle JDBC 2.0 Driver, the list looks like:
C:\xdk902\lib\xsu12.jar; C:\xdk902\lib\xmlparserv2.jar; directory_where_JDBC_Driver_resides\classes12.zip; C:\xdk902\lib\oraclexsql.jar; directory_where_XSQLConfig.xml_residesTo use Apache FOP for PDF Generation, you need to add:
C:\xdk902\lib\xsqlserializers.jar; FOPHOME/fop.jar; FOPHOME/lib/batik.jarMap the
To do this, select the Services tab in the JRun Administrator
and select the appropriate "JRun Servlet Engine for XXX" entry for the
Servlet Engine that corresponds to the web server that you are using. In
the example below, we'll show configuring the Servlet Engine for the (built-in)
JRun Web Server (JWS).
![]() |
Then click the Service Config button...
On the Service Config screen, select the Mappings tab.
![]() |
Click the Add button and make an entry for the
Map an
In this step, we want to map the virtual path
If you are using JRun together with another web server like Apache,
IIS, or others, the virtual directory mapping needs to be done using the
web server configuration file/utility. If you are using the JRun Web Server,
then you can configure this virtual path mapping from the JRun Adminstrator.
To do this, select the "jws" service and click on Service Config.
![]() |
Click on the Path Settings tab on the Service Config dialog,
and click the Add button as show below.
![]() |
Make an entry for a virtual path of
http://localhost:8000/xsql/index.html
This is done by editing the JServ configuration file named
# Oracle XML SQL Utility (XSU) wrapper.classpath=C:\xdk902\lib\xsu111.jar # Oracle XSQL Servlet wrapper.classpath=C:\xdk902\lib\oraclexsql.jar # Oracle JDBC (8.1.6) -- JDBC 1.x driver wrapper.classpath=directory_where_JDBC_Driver_resides\classes111.zip # Oracle XML Parser V2 (with XSLT Engine) wrapper.classpath=C:\xdk902\lib\xmlparserv2.jar # XSQLConfig.xml File location wrapper.classpath=directory_where_XSQLConfig.xml_resides # FOR Apache FOP Generation, Add # wrapper.classpath=C:\xdk902\lib\xsqlserializers.jar # wrapper.classpath=FOPHOME/fop.jar # wrapper.classpath=FOPHOME/lib/batik.jarTo use the Oracle JDBC 2.0 Driver, the list looks like:
# Oracle XML SQL Utility (XSU) wrapper.classpath=C:\xdk902\lib\xsu12.jar # Oracle XSQL Servlet wrapper.classpath=C:\xdk902\lib\oraclexsql.jar # Oracle JDBC (8.1.6) -- JDBC 2.0 driver wrapper.classpath=directory_where_JDBC_Driver_resides\classes12.zip # Oracle XML Parser V2 (with XSLT Engine) wrapper.classpath=C:\xdk902\lib\xmlparserv2.jar # XSQLConfig.xml File location wrapper.classpath=directory_where_XSQLConfig.xml_resides # FOR Apache FOP Generation, Add # wrapper.classpath=C:\xdk902\lib\xsqlserializers.jar # wrapper.classpath=FOPHOME/fop.jar # wrapper.classpath=FOPHOME/lib/w3c.jarMap the
To do this, you need to edit the JServ configuration file named
# Executes a servlet passing filename with proper extension in PATH_TRANSLATED # property of servlet request. # Syntax: ApJServAction [extension] [servlet-uri] # Defaults: NONE ApJServAction .xsql /servlets/oracle.xml.xsql.XSQLServletMap an
In this step, we want to map the virtual path
Alias /xsql/ "C:\xdk902\xdk\demo\java\xsql\"
http://localhost/xsql/index.html
This is done by editing the Tomcat startup script named
rem Set up the CLASSPATH that we need set cp=%CLASSPATH% set CLASSPATH=. set CLASSPATH=%TOMCAT_HOME%\classes set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\webserver.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\jasper.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\xml.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\servlet.jar set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\tools.jar REM Added for Oracle XSQL Servlet REM ----------------------------- set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xsu111.jar set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\oraclexsql.jar set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xmlparserv2.jar set CLASSPATH=%CLASSPATH%;directory_where_JDBC_Driver_resides\classes111.zip set CLASSPATH=%CLASSPATH%;directory_where_XSQLConfig.xml_resides REM FOR Apache FOP Generation, Add REM set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xsqlserializers.jar REM set CLASSPATH=%CLASSPATH%;FOPHOME/fop.jar REM set CLASSPATH=%CLASSPATH%;FOPHOME/lib/batik.jarTo use the Oracle JDBC 2.0 Driver, the list looks like:
rem Set up the CLASSPATH that we need set cp=%CLASSPATH% set CLASSPATH=. set CLASSPATH=%TOMCAT_HOME%\classes set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\webserver.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\jasper.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\xml.jar set CLASSPATH=%CLASSPATH%;%TOMCAT_HOME%\lib\servlet.jar set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\lib\tools.jar REM Added for Oracle XSQL Servlet REM ----------------------------- set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xsu12.jar set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\oraclexsql.jar set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xmlparserv2.jar set CLASSPATH=%CLASSPATH%;directory_where_JDBC_Driver_resides\classes12.zip set CLASSPATH=%CLASSPATH%;directory_where_XSQLConfig.xml_resides REM FOR Apache FOP Generation, Add REM set CLASSPATH=%CLASSPATH%;C:\xdk902\lib\xsqlserializers.jar REM set CLASSPATH=%CLASSPATH%;FOPHOME/fop.jar REM set CLASSPATH=%CLASSPATH%;FOPHOME/lib/batik.jarMap the
Tomcat supports creating any number of configuration "contexts" to better organize the web applications your site needs to support. Each context is mapped to a virtual directory path, and has its own separate servlet configuration information. XSQL Servlet comes with a pre-configured context file to make XSQL Servlet setup easier.
By default, Tomcat 3.1 and 3.2 come pre-configured with the following
contexts (defined by
Edit the
<Context path="/technology/test" docBase="webapps/test" debug="0" reloadable="true" /> <!-- | Define a Servlet context for the XSQL Servlet | | The XSQL Servlet ships with a .\WEB-INF directory | with its web.xml file pre-configured for C:\xdk902\xdk\demo\java\xsql | installation. +--> <Context path="/technology/xsql" docBase="C:\xdk902\xdk\demo\java\xsql"/>Note that the
<?xml version = '1.0' encoding = 'UTF-8'?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <servlet> <servlet-name>oracle-xsql-servlet</servlet-name> <servlet-class>oracle.xml.xsql.XSQLServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>oracle-xsql-servlet</servlet-name> <url-pattern> *.xsql </url-pattern> </servlet-mapping> </web-app>
![]() |
Note :
To add the XSQL Servlet to an existing context, add the servlet and
servlet-mapping entries that you find in |
Map an
This is already achieved by creating the
http://localhost:8080/xsql/index.html
![]() |
Note :
If you use Tomcat with an XML Parser (like the Sun Crimson Parser) that only supports DOM Leve 1 interfaces, then you must edit tomcat.bat to insure that the Oracle XML Parser's archive xmlparser.jar comes before the DOM Level 1 parser's archive in the classpath. For example, you could edit tomcat.bat to add the following line: REM NEED TO PUT xmlparserv2.jar FIRST before parser.jar set CP=C:\xdk902\lib\xmlparserv2.jar;%CP%just before the line: echo Using CLASSPATH: %CP% echo. set CLASSPATH=%CP% |
This is done by browsing the url http://localhost/servlet/admin after
starting the IIS Server, and clicking the VM Settings link under "Advanced"
in the sidebar.
![]() |
Add the four archives and one directory as shown above, by adding them one at a time and clicking the Submit button after each new entry.
Map the
Click on Configure under the "Servlets" heading in the sidebar
to browse the form where you register servlets. Enter a Servlet Name of
![]() |
Then, click on Aliases under "Servlets" in the sidebar.
Add an entry as shown below mapping
![]() |
Map an
Use the IIS Admin console to create an
![]() |
http://localhost/xsql/index.html
In this directory, run SQLPLUS. Connect to your database as
GRANT EXECUTE ON CTX_DDL TO SCOTT;Connect to your database as
GRANT QUERY REWRITE TO SCOTT;This allows SCOTT to create a functional index that one of the demos uses to perform case-insensitive queries on descriptions of airports.
Connect to your database as
Run the script
Change directory to the
![]() |
Note :
To properly experience the Scalable Vector Graphics demonstration, you need to install an SVG plugin into your browser like the Adobe SVG Plugin. |
Strongly Typed, User-Defined Collection
Untyped Collection based on a SQL statement
CREATE TYPE POINT AS OBJECT (X NUMBER, Y NUMBER);and have used your new
CREATE TABLE LOCATION ( NAME VARCHAR2(80), ORIGIN POINT );and have inserted a row into this
INSERT INTO LOCATION VALUES ( 'Someplace', POINT(11,17) ); COMMIT;Then, an XSQL page like
<xsql:query connection="demo" xmlns:xsql="urn:oracle-xsql">
SELECT name, origin
FROM location loc
WHERE loc.origin.x = {@x-coord}
</xsql:query>
...when requested using a URL like:
http://yourmachine.com/xsql/demo/point.xsql?x-coord=11produces the output:
<ROWSET> <ROW num="1"> <NAME>Someplace</NAME> <ORIGIN> <X>11</X> <Y>17</Y> </ORIGIN> </ROW> </ROWSET>This demonstrates how the nested
![]() |
Note :
See the supplied |
Taking the familar
<xsql:query connection="demo" xmlns:xsql="urn:oracle-xsql">
SELECT dname,
CURSOR( SELECT ename,sal
FROM emp
WHERE emp.deptno = dept.deptno) as employees /* Column Alias */
FROM dept
WHERE deptno = {@department}
</xsql:query>
Requesting this
http://yourserver.com/xsql/demo/empdept.xsql?department=10produces the resulting XML "datapage":
<ROWSET> <ROW num="1"> <DNAME>ACCOUNTING</DNAME> <EMPLOYEES> <EMPLOYEES_ROW num="1"> <ENAME>CLARK</ENAME> <SAL>2450</SAL> </EMPLOYEES_ROW> <EMPLOYEES_ROW num="2"> <ENAME>KING</ENAME> <SAL>5000</SAL> </EMPLOYEES_ROW> <EMPLOYEES_ROW num="3"> <ENAME>MILLER</ENAME> <SAL>1300</SAL> </EMPLOYEES_ROW> </EMPLOYEES> </ROW> </ROWSET>Note that the second column in the
Since the
One or more
The SQL statement that may appear within the
Any SQL statement can be included in an
Of course, by using these query techniques in the
The
The fact that
A database table
Let's say that the source document is an XML news feed like what you'll see if you browse the following URL from www.moreover.com ...
http://www.moreover.com/cgi-local/page?index_xml+xmlA shortened version of such a resulting XML document looks like this:
<?xml version="1.0"?> <!DOCTYPE moreovernews SYSTEM "http://www.moreover.com/xml/moreovernews.dtd"> <moreovernews> <article id="4227581"> <url>http://d.moreover.com/click/here.pl?x4227575</url> <headline_text>Austin: webMethods gets deal with Dell</headline_text> <source>dbusiness.com</source> <media_type>text</media_type> <cluster>XML and metadata news</cluster> <tagline>Austin</tagline> <document_url>http://washington.dbusiness.com/</document_url> <harvest_time>Oct 30 1999 7:08AM</harvest_time> <access_registration> </access_registration> <access_status> </access_status> </article> <article id="4212701"> <url>http://d.moreover.com/click/here.pl?x4212698</url> <headline_text>Microsoft continues XML push with resource kit</headline_text> <source>InfoWorld</source> <media_type>text</media_type> <cluster>XML and metadata news</cluster> <tagline></tagline> <document_url>http://www.infoworld.com/</document_url> <harvest_time>Oct 29 1999 7:27AM</harvest_time> <access_registration> </access_registration> <access_status> </access_status> </article> <article id="4202251"> <url>http://d.moreover.com/click/here.pl?x4202247</url> <headline_text>IBM Brings XML To MQSeries</headline_text> <source>Internet Week</source> <media_type>text</media_type> <cluster>XML and metadata news</cluster> <tagline></tagline> <document_url>http://www.internetwk.com/</document_url> <harvest_time>Oct 28 1999 4:28PM</harvest_time> <access_registration> </access_registration> <access_status> </access_status> </article> <article id="4082434"> <url>http://d.moreover.com/click/here.pl?x4082432</url> <headline_text>XML leader OnDisplay's travel clients praised</headline_text> <source>Web Travel News</source> <media_type>text</media_type> <cluster>XML and metadata news</cluster> <tagline></tagline> <document_url>http://www.webtravelnews.com/</document_url> <harvest_time>Oct 20 1999 7:34AM</harvest_time> <access_registration> </access_registration> <access_status> </access_status> </article> </moreovernews>Next, let's say that you have a table called
CREATE TABLE newsstory( id NUMBER PRIMARY KEY, title VARCHAR2(200), url VARCHAR2(200), source VARCHAR2(200) );And further, let's suppose that you want to insert information from the XML news feed from Moreover.com into this table.
So, we need to produce an XSL transformation that transforms the information
in the XML news feed from Moreover.com into the canonical format that
We start by using an XSQL page to quickly produce one row of canonical
query results from the
<?xml version="1.0"?> <query connection="demo" max-rows="1"> SELECT * FROM NEWSTORY </query>We can either request this page through the webserver, or more conveninently for this job, use the XSQL Command Line Utility to quickly put the XSQL Page's output into a file:
xsql newstory.xsql newsstory.xmlThis command processes the
<?xml version = '1.0'?> <ROWSET> <ROW num="1"> <ID>1911</ID> <TITLE>Some Title</TITLE> <URL>http://somemachine/somepage.html</URL> <SOURCE>SomeSource</SOURCE> </ROW> </ROWSET>We can take this one row of canonical output from a "
Remove the
Remove any elements corresponding to columns whose values will be assigned by database triggers, like the ID column will be in this example,
Surround the
Replace the literal text between the
query produces the following XSL Transformation:
<?xml version = '1.0'?> <ROWSET xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:for-each select="moreovernews/article"> <ROW> <TITLE><xsl:value-of select="headline_text"/></TITLE> <URL><xsl:value-of select="url"/></URL> <SOURCE>Moreover.com</SOURCE> </ROW> </xsl:for-each> </ROWSET>Which illustrates that we have:
<ROWSET xmlns:xsl="http://www.w3.org/1999/XSL/Transform">Added the
<xsl:for-each select="moreovernews/article">so that for each
Removed the
Changed the:
<TITLE>Some Title</TITLE> <URL>http://somemachine/somepage.html</URL>tags to:
<TITLE><xsl:value-of select="headline_text"/></TITLE> <URL><xsl:value-of select="url"/></URL>to plug-in the value of the current
Hard-coded the value of the
java oracle.xml.parser.v2.oraxsl moreover.xml moreover-to-newsstory.xsl out.xml
![]() |
Note :
Since the <!DOCTYPE moreovernews SYSTEM "http://www.moreover.com/xml/moreovernews.dtd">declaration with an java -DproxySet=true -DproxyHost=proxyServerName -DproxyPort=80 oracle.xml.parser.v2.oraxsl ... |
If we use Internet Explorer to browse the resulting
![]() |
If we pass this resulting target document to the
The last step before showing how to tie it all together using Java or XSQL Pages is to create the database trigger to automatically assign the value of the ID column on insert. Assuming we have a sequence named newsstory_id_seq lying around, the code looks like:
CREATE TRIGGER newsstory_autoid BEFORE INSERT ON newsstory FOR EACH ROW BEGIN SELECT newsstory_id_seq.nextval INTO :new.id FROM dual; END;
Create an XSL Transformation that transforms the inbound document into the canonical format for this table or view,
We saw a "cookbook" approach above for how to do this easily based on
a
Transform the inbound document into the canonical format for the table or view into which you want to insert it, and
Let
<xsql:insert-request table="tableorviewname" transform="transformname.xsl"/>to the top of your XSQL page to perform the four steps above automatically. So, for example, the following XSQL Page would accept information posted through HTTP in the Moreover.com moreovernews format, and insert it into the
<?xml version="1.0?> <xsql:insert-request xmlns:xsql="urn:oracle-xsql" connection="demo" table="newsstory" transform="moreover-to-newsstory.xsl"/>Running this program retrieves the newsstories and inserts them into our
Due to the nature of this news feed, news stories stay in the feed for
a few days. If we want to avoid inserting the same story over and over
again, we can easily do that by making sure we don't insert a story unless
its Title and URL are a unique combination in our
Let's implement this behavior using a database
Since
CREATE VIEW newsstoryview AS SELECT * FROM newsstoryThen we can create the
CREATE OR REPLACE TRIGGER insteadOfIns_newsstoryview INSTEAD OF INSERT ON newsstoryview FOR EACH ROW DECLARE notThere BOOLEAN := TRUE; tmp VARCHAR2(1); CURSOR chk IS SELECT 'x' FROM newsstory WHERE title = :new.title AND url = :new.url; BEGIN OPEN chk; FETCH chk INTO tmp; notThere := chk%NOTFOUND; CLOSE chk; IF notThere THEN INSERT INTO newsstory(title,url,source) VALUES (:new.title,:new.url,:new.source); END IF; END;Here we are assuming that "uniqueness" of a story is defined by the combination of its
CREATE UNIQUE INDEX newsstory_unique_title_url on newsstory(title,url);We've written the body of the trigger in PL/SQL to demonstrate that you can mix and match PL/SQL and Java in this solution, but in Oracle8i we could have also written the INSTEAD OF trigger to call a Java Stored Procedures as well to perform the uniqueness check.
Finally, the only thing left to do is to change the xsql:insert-request
action element above to use the
<?xml version="1.0?> <xsql:insert-request xmlns:xsql="urn:oracle-xsql" connection="demo" table="newsstoryview" transform="moreover-to-newsstory.xsl"/>Now, only unique newstories from the Moreover XML news feed will be inserted.
![]() |
Note :
Using the same |
The
<?xml version="1.0"?> <page connection="demo" xmlns:xsql="urn:oracle-xsql"> <xsql:insert-request table="newsstoryview" transform="moreover-to-newsstory.xsl"/> <lateststories> <xsql:query tag-case="lower" max-rows="5" rowset-element="" row-element="story" > select * from newsstory order by id desc </xsql:query> </lateststories> </page>The XSQL page above inserts any posted XML document containing
![]() |
When XML is posted to a web server through HTTP, it's ContentType is
<request> <parameters> <firstparamname>firstparamvalue</firstparamname> : <lastparamname>lastparamvalue</lastparamname> </parameters> <session> <firstparamname>firstsessionparamvalue</firstparamname> : <lastparamname>lastsessionparamvalue</lastparamname> </session> <cookies> <firstcookie>firstcookievalue</firstcookiename> : <lastcookie>firstcookievalue</lastcookiename> </cookies> </request>and then allows an
![]() |
Note :
If multiple parameters are posted with the same name, then they will automatically be "row-ified" to make subsequent processing easier. This means, for example, that a request which posts or includes the following parameters: <request> <parameters> <row> <id>101</id> <name>Steve</name> </row> <row> <id>102</id> <name>Sita</name> </row> <operation>update</operation> </parameters> : </request> |
Using an
<xsql:insert-request table="newsstoryview" transform="request-to-newsstoryview.xsl"/and by referencing the name of the
<?xml version = '1.0'?> <ROWSET xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:version="1.0"> <xsl:for-each select="request/parameters"> <ROW> <TITLE><xsl:value-of select="title_field"/></TITLE> <URL><xsl:value-of select="url_field"/></URL> <SOURCE>User-Submitted</SOURCE> </ROW> </xsl:for-each> </ROWSET>If the above XSQL page were saved as
<html> <body> Insert a new news story... <form action="insertnewsform.xsql" method="post"> <b>Title</b><input type="text" name="title_field" size="30"><br> <b>URL</b><input type="text" name="url_field" size="30"><br> <br> <input type="submit"> </form> <body> </html>If we let a user fill-out and post the form as-is, they will get raw XML as a response from the
Using the mechanism we learned in the previous section for associating
XSL Stylesheets with XSQL Pages, we can include an
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<head>
<title>Latest Stories</title>
</head>
<body>
<h2>Thanks for your Story!</h2>
Here's a list of the latest stories we've received...
<table border="0" cellspacing="0">
<xsl:for-each select="page/lateststories/story">
<tr>
<td><a href="{url}"><xsl:value-of select="title"/></a></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
This means the <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="lateststories.xsl"?> <page connection="demo" xmlns:xsql="urn:oracle-xsql"> <xsql:insert-request table="newsstoryview" transform="request-to-newsstory.xsl"/> <lateststories> <xsql:query tag-case="lower" max-rows="5" rowset-element="" row-element="story" > select * from newsstory order by id desc </xsql:query> </lateststories> </page>Now when the user browses the
![]() |
...then rather than seeing the raw XML datagram returned by the
![]() |
as an HTML page instead of as raw XML.
So in addition to being possible for developers by using Java programs that leverage the Oracle XML SQL Utility directly, we've seen that it's easy to insert XML-based information into Oracle database tables or views without programming using XSQL Pages and XSLT Transformations.
![]() |
Note :
Here we've used simple examples with simple tables, however
Insert "fragments" or "chunks" of XML elements and their content (from an entire document to any desired granularity of sub-structure) into a CLOB column or an object type with a CLOB attribute. |
| Description of Demonstrations
|
|
| Demonstration Name ( |
Comments |
| Hello World ( |
Simplest possible XSQL page. |
| Do You XML Site ( |
XSQL page which shows how a simple, data-driven web site can be built
using an XSQL page which makes clever use of SQL, XSQL-substitution variables
in the queries, and XSLT for formatting the site.
Demonstrates using substitution parameters in both the body of SQL query
statements within |
| Employee Page ( |
XSQL page showing XML data from the EMP table, using XSQL page parameters
to control what employees are returned and what column(s) to use for the
database sort. Uses an associated XSLT Stylesheet for format the results
as an HTML Form containing the emp.xsql page as the form |
| Insurance Claim Page ( |
Demonstrates a number of sample queries over the richly-structured,
Insurance Claim object view. The |
| Invalid Classes Page ( |
XSQL Page which uses |
| Airport Code Validation ( |
XSQL page which returns a "datagram" of information about airports
based on their three-letter code. Demonstrates using the The When you type in a three-leter airport code into this web page, some JavaScript under the covers fetches the XML datagram from the XSQL Servlet over the web corresponding to information for the airport code you typed in. If the return indicates that there was no exact match, the builds up a dynamic "picklist" of possible matches based on the information returned in the XML "datagram" from the XSQL Servlet. |
| Airport Code Display ( |
Demonstrates using the same XSQL page as the previous example but supplying an XSLT Stylesheet name in the request. This causes the airport information to be formatted as an HTML form instead of being returned as raw XML. |
| Airport Code Display ( |
Demonstrates returning Airport information as a SOAP Service. |
| Emp/Dept Object View Demo ( |
Demonstrates using an object view to group master/detail information
from two existing "flat" tables like EMP and DEPT. The The |
| Adhoc Query Visualization ( |
Demonstrates passing the entire SQL query and XSLT Stylesheet to use as parameters to the server. |
| XML Document Demo ( |
Demonstrates inserting XML documents into relational tables. The Try inserting the text of the document in The The demo uses the client-side XML features of Internet Explorer 5.0 to check the document for well-formedness before allowing it to be posted to the server. |
| XML Insert Request Demo ( |
Demonstrates posting XML from a client to an XSQL Page that handles
inserting the posted XML information into a database table using the In this case, the program doing the posting of the XML is a client-side
web page using Internet Explorer 5.0 and the Try copying and pasting the example The |
| SVG Demo ( |
The |
![]() |
Note :
Some of the material included in this document is excerpted from Building Oracle XML Applications by permission of O'Reilly and Associates. |