Customizing Content With Oracle XML DB and J2EE features

Oracle XML DB features used in the application

December 2002
  Oracle9i  

Oracle XML DB is not some separate server but rather the name for a distinct group of technologies related to high-performance XML storage and retrieval that are available within the familiar Oracle database. Oracle XML DB can also be thought of as an evolution of the Oracle database that encompasses both SQL and XML data models in a highly interoperable manner, thus providing native XML support.

Oracle XML DB can be used in conjunction with Oracle XML Developer's Kit (XDKs). XDKs provide common development-time utilities that can run in the middle tier in Oracle9iAS or in Oracle9i database.

Lets examine how Oracle XML DB features are used for following features of the application.

  • News Items stored in XMLTYPE based on XML schema.
    In the current XMLNews sample application, Oracle XML DB features are used to manage news items in the XML database. Basically, the news item information is stored as XML document in the XMLTYPE datatype. The XML document is created to comply with an XML Schema. In order to associate an XML Schema with an XMLTYPE column, the schema needs to be registered in the database.

    Following SQL*Plus script will show how schema is registered in the Oracle database.
    -- register the 'NewsItem' schema with the database
    DECLARE
    doc VARCHAR2(2500) := '<schema
    targetNamespace="/NewsItem.xsd"
    xmlns:ni="/NewsItem.xsd"
    xmlns="http://www.w3.org/2001/XMLSchema"
    xmlns:xdb="http://xmlns.oracle.com/xdb">
    <complexType name="NewsItemType">
    <sequence>
    <element name="title">
    <simpleType>
    <restriction base="string"></restriction>
    </simpleType>
    </element>
    <element name="description" type="string" xdb:SQLType="CLOB">
    </element>
    <element name="entered_date">
    <simpleType>
    <restriction base="string"></restriction>
    </simpleType>
    </element>
    ..........
    ..........
    </sequence>
    </complexType>
    <element name="NewsItem" type="ni:NewsItemType"/>
    </schema>';
    BEGIN
    DBMS_XMLSCHEMA.REGISTERSCHEMA('http://www.oracle.com/NewsItem.xsd', doc);
    END;

    Here is the structure of newsitems table whose XMLTYPE column is based on the above schema in the database.

    CREATE TABLE newsitems (
    id NUMBER(10) CONSTRAINT pk_newsitems PRIMARY KEY,
    submitted_by VARCHAR2(20) NOT NULL,
    approve_flag VARCHAR2(12) DEFAULT 'FALSE',
    archive_flag VARCHAR2(6) DEFAULT 'FALSE',
    newsinfo sys.xmltype NOT NULL
    )
    xmltype column newsinfo
    XMLSCHEMA "http://www.oracle.com/NewsItem.xsd"
    element "NewsItem";

  • Oracle XML DB functions used in the application

    Oracle XML DB features are used to create, update, query and generate XML documents. Also, applying XSL to the generated XML documents is done at the database layer itself.   NewsItemSession Local EJB has the code implementation for Oracle XML DB features in the application. 

    As mentioned earlier in the overview of the application, every news item is created as an XMLTYPE in the database which will adhere to the schema NewsItem.xsd, registered in the database. Some of the Oracle XML DB functions used in the application are as follows. Refer code in  NewsItemSessionBean.java for more details.


    1. sys.XMLType.createXML() : This function is used to create an XMLTYPE document for the newsinfo XMLTYPE column in the newsitem table.
      Example:

       
      INSERT INTO Newsitems(id, submitted_by, approve_flag, archive_flag, newsinfo)
      VALUES(1, 'admin', 'TRUE', 'FALSE',
      sys.XMLType.createXML('<NewsItem xmlns="/NewsItem.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="/NewsItem.xsd
       http://www.oracle.com/NewsItem.xsd">
      <title>News title</title>
      <description>News Description</description>
      <entered_date>'||to_date(sysdate, 'DD-MON-YYYY')||'</entered_date>
      <expiry_date>12-Dec-2002</expiry_date>
      <imagepointer>picture.jpg</imagepointer>
      <catid>1</catid>
      <subcatid>4</subcatid>
      <typeid>12</typeid>
      </NewsItem>'));


    2. extract() : This function is used to extract XML elements from newsinfo column in the database.
      Example:

        SELECT id, extract(newsinfo, '/a:NewsItem/title/text()',
      'xmlns:a="/NewsItem.xsd"').getStringval()
      FROM newsitems


    3. SYS_XMLAGG() and SYS_XMLGEN():  sys_xmlagg() function aggregates all newsinfo XML documents obtained for a query. sys_xmlgen() will return well-formed xml documents for a query which will be aggregated by sys_xmlagg() function.
      Example:

        SELECT SYS_XMLAGG(SYS_XMLGEN(e.newsinfo)).getClobval() e FROM newsitems e WHERE e.id IN (1,2,3)

    4. XMLTransform()The XMLTransform() function takes in an XMLType instance and an XSLT stylesheet. It applies the stylesheet to the XML document and returns a transformed XML instance. This XML document will be nothing but HTML document. In the current application, while displaying dynamic or static news, this function is used at the database and only HTML content is returned to the calling methods to be returned to the user's browsers.
      Example:

        select xmltransform(xmltype('<ROWSET>
      <NewsItem >
      <title>news 1</title>
      <description>news 1
      Enter
      Description here ..</description>
      <location>news 1 Location</location>
      <entered_date>07-Oct-2002</entered_date>
      <expiry_date>12-Jan-2003</expiry_date>
      <imagepointer/>
      <catid>1</catid>
      <subcatid>3</subcatid>
      <typeid>7</typeid>
      </NewsItem>
      <NewsItem >
      <title>news 2</title>
      <description>news 2 desc Enter Description here ..</description>
      <location>bang</location>
      <entered_date>07-Oct-2002</entered_date>
      <expiry_date>12-Oct-2002</expiry_date>
      <imagepointer/>
      <catid>1</catid>
      <subcatid>3</subcatid>
      <typeid>7</typeid>
      </NewsItem>
      </ROWSET>'),
      xmltype('<?xml version="1.0"?>
      <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <xsl:output indent="yes"/>
      <xsl:template match="/technology/">
      <HTML>
      <BODY>
      <TABLE border="1">
      <xsl:for-each select="/technology/ROWSET/NewsItem">
      <TR>
      <TD width="50%"><xsl:value-of select="title"/></TD>
      <TD width="50%"><xsl:value-of select="description"/></TD>
      </TR>
      </xsl:for-each>
      </TABLE>
      </BODY>
      </HTML>
      </xsl:template>
      </xsl:stylesheet>')).getClobval() from dual
      /


  • Generating documents
    • Static/Batch News Pages are built from XML documents pregenerated at intervals left to the discretion of the news system administrator.
  • Import News Items from a RSS formatted file.
    • Dynamic News can import XML documents that conform to the Rich Site Summary ( RSS) standard. Developed by Netscape as a way to share data channels, RSS has been used at Web sites such as my.netscape.com and slashdot.org.

      An application can use RSS to syndicate its news pages (making them available to RSS hosts) and to aggregate news from other RSS sites. For example, Dynamic News includes the oracle.otnsamples.xmlnews.business.RSSHandler class. It uses a specified DTD to parse and extract news items from a specified file, and then it stores the items in a Hashtable. The class also provides a method that returns the elements in that Hashtable.

      News import can be done only by system administrator. The news title and description are imported to the application and saved in the database.

Static/Batch News Page

Dynamic News generates static pages to display all available news items. These pages are built at intervals set by the news system administrator (for example, every hour on the hour); otherwise, they don't change. Static pages are useful in any application where data doesn't change very often; for example, when publishing daily summaries from ERP or customer applications. Because the content is static, it's more efficient to pregenerate a page than to build one for each user who requests it.

Generating batch news involves generating the main content and top news. The admin executes a batch process (implemented in the BatchController.java ) that queries the database, gets the XML document, applies the appropriate XSL stylesheet. This HTML document is then written to a local file where the application server is running. When an end-user invokes Dynamic News to display all news, the controller gets the HTTP request, then just returns the HTML page formatted for the end-user's browser
.

Here is the code snippet from NewsItemSessionBean.java to extract batch news as a String of XML document for a given set of news items ids. Since Batch generation will require both main content and top news to be generated, this common method will process accordingly.

 
public String getNewsItemsById(ArrayList idList, String newsType) throws BusinessException {
StringBuffer newsString = new StringBuffer();
String data = "";
try {

// create a StringBuffer to form the query
StringBuffer query = new StringBuffer();
// depending on the newsType TOP news or TOP news Content or the
// batch news content, create the query.
if (newsType.equals("CONT")) {
query.append("SELECT SYS_XMLAGG(SYS_XMLGEN");
query.append("(e.newsinfo)).getClobval() e ");
query.append(" FROM newsitems e ");
query.append(" WHERE e.id IN ( ");
// for all the ids passed, loop through to add ',' between ids
for(int i = 0;i < idList.size();i++) {
if(i > 0) {
query.append(",");
}
query.append("?");
}
query.append(" )");
// execute the query using DBBroker class
data = DBBroker.getDBBroker("xmlnewsDB").executeClob(query.toString(), idList);
} else if ((newsType.equals("TOP"))||
(newsType.equals("TOPCONT"))) {
query.append(" SELECT SYS_XMLAGG(SYS_XMLAGG(XMLELEMENT(\"NEWSINFO\",");
query.append(" e.newsinfo))).getClobval() e");
query.append(" FROM newsitems e, topfivenews t ");
query.append(" WHERE e.id = t.news_id AND ");
query.append(" e.id IN (SELECT news_id FROM topfivenews) ");
query.append(" GROUP BY t.topfiveorder ");
// execute the query using DBBroker class
data = DBBroker.getDBBroker("xmlnewsDB").executeClob(query.toString(),null);
}

} catch(Exception ex) {
.............................................
}
return data; // return xmlString
}

Personalized/Dynamic News Page

The application builds dynamic pages on demand by pulling items directly from the database. End-users access the "Preferences" to choose categories, subcategories, and types (for example, Entertainment - Movies - Review). Based on these user preferences, the news items are pulled out of the database.
 Unlike the other runtime models, the administrator does not pregenerate HTML documents. Instead, the Controller (NewsController.java ) queries the database for news items based on the end-user's customization choices. The application uses Container-managed-Relationships(CMR) method to store user preferences in the database. In the database, the XML document is obtained for the query is transformed using an XSL stylesheet into an HTML page for the user's browser.  When the user invokes preferred news page, the HTML content is directly written onto the browser's page.

Dynamic pages are useful for delivering up-to-the-minute information, such as latest news. They are also useful for delivering historical data, such as the closing price of any specified stock on any day in the last 10 years. It would be impractical (at best) to pregenerate documents for every possible request, but straightforward and efficient to pull the figures from the database.

You could refer to NewsItemSessionBean.java and its method getUserPreferredNews which gets user preferred news based on user preferences for more details on code.


Post you comments in the OTN Sample Code forum
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy