Returning XMLBeans from a Database Control

The following topic explains how to return XMLBean types from both both RowSet and custom database controls.

An XMLBean is essentially an XML document with a Java API attached to it. The API is used for parsing and manipulating the data in the XML document. A typical XMLBean might represent database data in the following form.

<!DOCTYPE XCustomer> 
<XCustomer xmlns="java:///database/customer_db" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <XCustomerRow> 
        <CUSTID>1</CUSTID> 
        <NAME>Fred Williams</NAME> 
        <ADDRESS>123 Slugger Circle</ADDRESS> 
    </XCustomerRow> 
    <XCustomerRow> 
        <CUSTID>2</CUSTID> 
        <NAME>Marnie Smithers</NAME> 
        <ADDRESS>5 Hitchcock Lane</ADDRESS> 
    </XCustomerRow> 
    <XCustomerRow> 
        <CUSTID>3</CUSTID> 
        <NAME>Bill Walton</NAME> 
        <ADDRESS>655 Tall Timbers Road</ADDRESS> 
    </XCustomerRow> 
</XCustomer> 

The data can be accessed and manipulated using the XMLBean's API. For example, assume that custBean represents the XML document above. The following Java code extracts the name of the first customer, Fred Williams, from the document.

String name = custBean.getXCustomer().getXCustomerRowArray(1).getNAME();

Retrofitting database controls to return XMLBeans rather than RowSets, ResultSets, or Iterators, is a powerful technique because there are few restrictions on where XMLBeans can be imported. This is not the case with ResultSets and Iterators, which cannot be passed directly to web-tier classes (web services and page flows). Also, data in an XMLBean form is very easy to manipulate because there is a rich API attached to the XMLBean.

Creating a Schema

The first step in using XMLBean classes is creating a schema from which the XMLBean classes can be generated. The schema you create for a database control must be capable of modeling the sorts of data returned from the database.

If you write your own schema, at a minimum, the schema's elements should have the same names as the fields in the database, which allows data returned from the database to be automatically mapped into the XMLBean.

To autogenerate a schema for a database or RowSet control, follow this procedure:

  1. Display the database control file in Design View.
  2. Select a method that returns data from the database. (A method that does not return data, such as a CREATE TABLE statement will not work.)

  3. On the Properties Editor tab, in the section labeled sql, select the property named rowset-name.

  4. Enter a RowSet name. (The name you enter becomes part of the schema, and the XMLBean classes derived from the schema.)

  5. Select and copy the schema text from the Edit RowSet Schema dialog. (The dialog does not support right-clicking, you must use Ctrl+C to copy the schema text.)

    Note that XCustomer appears in the schema in two places:

    <xsd:element name="XCustomer" ...

    <xsd:element name="XCustomerRow">


  6. Cancel out of the dialog and save the schema text in an XSD file in a Schemas project. Make sure that the XSD file begins with the element <?xml version="1.0"?>.

When the XSD file is compiled, XMLBean types are generated that can be returned by the methods in the database control. The XMLBean classes appear in the Schema project's XML Bean Classes folder.

             

Editting Schemas to Create New "Document" Types

Note that only one of the generated types is a "Document" XMLBean type: XCustomerDocument. The other types, XCustomerDocument.XCustomer and XCustomerDocument.XCustomer.XCustomerRow, can only be used with reference to the "Document" type. This distinction is especially important because only "Document" types are eligible for direct participation in a business process, or to be passed to a web service. For this reason you may want to edit your schema to include "Document" types corresponding to other types in the Schema, especially if you have a very large schema with many nested types defined in terms of a single "Document" type.

To generate a new Document type for some element, move that element so that it becomes a top-level element in the schema. In the following example, the XCustomerRow element has been moved to the top-level of the schema: its original position has been replaced with a reference element: <xsd:element ref="XCustomerRow"/>.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema targetNamespace="java:///database/customer_db" xmlns="java:///database/customer_db" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wld="http://www.bea.com/2002/10/weblogicdata" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:element name="XCustomer" wld:DefaultNamespace="java:///database/customer_db" wld:RowSet="true">
     <xsd:complexType>
      <xsd:choice maxOccurs="unbounded">
       <xsd:element ref="XCustomerRow"/>
      </xsd:choice>
     </xsd:complexType>
    </xsd:element>
    <xsd:element name="XCustomerRow">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="CUSTID" type="xsd:int" wld:JDBCType="INTEGER" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="NAME" type="xsd:string" wld:JDBCType="VARCHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="ADDRESS" type="xsd:string" wld:JDBCType="VARCHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="CITY" type="xsd:string" wld:JDBCType="VARCHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="STATE" type="xsd:string" wld:JDBCType="CHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="ZIP" type="xsd:string" wld:JDBCType="VARCHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="AREA_CODE" type="xsd:string" wld:JDBCType="CHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
          <xsd:element name="PHONE" type="xsd:string" wld:JDBCType="CHAR" minOccurs="0" wld:TableName="WEBLOGIC.CUSTOMER" nillable="true"></xsd:element>
        </xsd:sequence>
        <xsd:anyAttribute namespace="http://www.bea.com/2002/10/weblogicdata" processContents="skip"></xsd:anyAttribute>
      </xsd:complexType>
    </xsd:element>
</xsd:schema>

There are now two top-level elements, XCustomer and XCustomerRow, which compile into two corresponding "Document" types: XCustomerDocument and XCustomerRowDocument.

Returning a XMLBean Types from Control Methods

Once you have generated XMLBean types that model the database data, you can import these types into your database control.

    import databaseCustomerDb.XCustomerDocument;
    import databaseCustomerDb.XCustomerDocument.XCustomer;
    import databaseCustomerDb.XCustomerDocument.Factory;

XMLBean types can be returned from the control's methods.

    /**
     * @jc:sql statement="SELECT custid, name, address FROM customer" 
     */
     public XCustomerDocument findAllCustomersDoc(); 

 

The data returned from the query is automatically mapped into the XMLBean because the names of the database fields match the fields of the XMLBean.

Related Topics

Java Types Generated from User-Derived Schema Types

@jc:sql Annotation

Samples

CustomerDB_XMLBean Sample

ItemsDB_XMLBean Sample