PREVNEXTINDEX
 

10 Tutorial: Using jXTransformer Queries


This chapter contains a step-by-step tutorial that shows you how to create a jXTransformer query using the DataDirect Query Builder for SQL/XML (the Builder). It also shows you how to embed the query in a Java using the jXTransformer API.

This tutorial steps you through the process of constructing the following jXTransformer query, which logically can be divided into two parts: the first part specifies document-level constructs and the second part specifies the data to be retrieved and defines the structure of the XML document.

NOTE: The preceding jXTransformer query example can be found in the JXTRExample4.java file in the examples/src/examples/jxtrapi directory in your Connect for SQL/XML installation directory. For information on populating your database with test data and using this example, refer to the examples_readme.txt file in the examples directory.

Our jXTransformer query example generates an XML document that looks like this:

<!--jxtr Example4--> 
<!DOCTYPE exns:example4 SYSTEM "example4.dtd"> 
<?xml-stylesheet type="test/xsl" href="file://example4.xsl"?> 
<exns:example4  
rootatt1='example4' 
xmlns="http://www.jxtrdemo/default"       
xmlns=exns="http://www.jxtrdemo/example4"> 
   <empinfo exns:id='1' name='Marshall'> 
     <project name='Medusa' task='Analysis'></project> 
     <project name='Medusa' task='Documentation'></project> 
     <project name='Medusa' task='Planning'></project> 
     <project name='Medusa' task='Testing'></project> 
     <project name='Phoenix' task='Analysis'></project> 
     <project name='Phoenix' task='Documentation'></project> 
   </empinfo> 
   <empinfo exns:id='2' exns:name='Ayers'> 
     <project name='Hydra' task='Analysis'></project> 
     <project name='Hydra' task='Documentation'></project> 
     <project name='Python' task='Analysis'></project> 
     <project name='Python' task='Development'></project> 
   </empinfo> 
   <empinfo exns:id='3' exns:name='Simpson'> 
     <project name='Pegasus' task='Analysis'></project> 
     <project name='Pegasus' task='Testing'></project> 
   </empinfo> 
   <empinfo exns:id='4' exns:name='O&apos;Donnel'> 
     <project name='Centaur' task='Analysis'></project> 
     <project name='Centaur' task='Documentation'></project> 
     <project name='Centaur' task='Planning'></project> 
   </empinfo> 
   <empinfo exns:id='5' exns:name='Jenkins'> 
     <project name='Centaur' task='Analysis'></project> 
     <project name='Centaur' task='Testing'></project> 
   </empinfo> 
   </exns:example4> 

This tutorial uses this jXTransformer query example to demonstrate how to accomplish the following tasks:

(SELECT

xml_element('project',

xml_attribute('name',p.Name),

xml_attribute('task',a.Task))

FROM Projects p, Assignments a

WHERE p.ProjId=a.ProjId and a.EmpId=e.EmpId))

For the purposes of this tutorial, we refer to the nested query as the child query and the query that contains the nested query as the parent query.

Complete the tasks described in the next sections to create the jXTransformer query in our example. These tasks include:

Creating the Builder Project

  1. Start the Builder. How you start the Builder depends on your platform:
  2. During a normal installation, the builder.bat file and builder.sh script are automatically customized to include the path to your JDK. If the installer was unable to detect a required JDK or you want to change the JDK to be used, refer to the DataDirect Connect for SQL/XML Installation Guide for instructions on configuring the startup file for the Builder.

  3. Open a new Builder project for the jXTransformer query by selecting File / New Project. The New Project dialog box appears.


  4. From the drop-down list, select jXTransformer.
  5. Click OK. An untitled project node appears in the Tree view of the jXTransformer Statement window.

  6. jXTransformer Query window in tree view

  7. Save the jXTransformer query project by selecting File / Save Project As and specifying example4.jxbas the filename of the project. Notice that the project node is renamed to example4. As you work with this example, you can save your changes to the project file at any time by selecting File / Save Project.

Our jXTransformer query example contains a nested, or child, query as shown in the following example.

As you build the query in the example, you will construct the parent query first. Then, you will construct the child query.

NOTE: Typically, you would construct the part of the query that represents the structure of the XML document first, and then, insert document-level constructs in the query. If you prefer, however, you can insert document-level constructs first (see "Specifying Document-Level Constructs in the jXTransformer Query" for instructions). Or, you can set the document-level constructs in the jXTransformer API (see "Using a jXTransformer Query in a Java Application" for instructions).

Constructing the Parent Query in the Builder

  1. First, create a Base SQL Query for the parent query. The Base SQL Query is required and helps define the data to be retrieved. It also facilitates the process of constructing the query. To create a Base SQL Query, right-click the project node and select Insert / Base SQL Query Node. The Base SQL Query Node dialog box appears.

  2. Base SQL Query Node dialog box

  3. Type the following Base SQL Query for the parent query:
  4. SELECT

    e.EmpId,

    e.LastName

    FROM Employees e WHERE e.EmpId between ? and ?

    The Base SQL Query accomplishes the following tasks:

    Notice that the Where clause in our example specifies a filter on the Select statement of the parent query and contains parameter markers. Parameter markers are placeholders for values, represented by question marks (?). Later, this tutorial will show you how to set the values of the parameter markers using the jXTransformer API. See "Using a jXTransformer Query in a Java Application" for instructions.

  5. Click OK. The Builder checks the Base SQL Query for syntax. The Base SQL Query node appears in the project tree.

  6. jXTransformer Query window with the Base SQL Query node added

    Now that you have defined which data to retrieve from the database for the parent query, you can define the XML structure, including the hierarchical relationships of the data.

    So, examine the parent query in our example. You need to create an XML element that contains related employee information, including employee ID, last name of the employee, and basic project information for that employee.



    Notice that the element named empinfo in the parent query is a parent to the following attributes and nested query:

    TIP: When specifying table names, you must use unique table aliases (for example, Employees e).

    (SELECT

    xml_element('project',

    xml_attribute('name',p.Name),

    xml_attribute('task',a.Task))

    FROM Projects p, Assignments a

    WHERE p.ProjId=a.ProjId and a.EmpId=e.EmpId))

    Notice that the Where clause in the nested query creates a link between the database tables, Projects and Assignments and Assignments and Employees.

  7. Because the element only contains child constructs, you can create an ELEMENT node named empinfo with an empty value. Right-click the Base SQL Query node, and select Insert / Element / Empty. The Element Node dialog box appears.

  8. Element Node dialog box

  9. In the Name field, type empinfo.
  10. Click OK. The ELEMENT node appears in the project tree.

  11. jXTransformer Query window with the ELEMENT node added

    TIP: Because keys uniquely identify rows in the database, we recommend that you use keys when possible to facilitate the performance of data retrieval.

  12. Now, add an attribute key named exns:id that will retrieve the employee ID from the database column e.EmpId. Because this attribute key will be a child of the element named empinfo, right-click the ELEMENT node named empinfo. Select Insert / Attribute node / As Select Expression. The Attribute Node dialog box appears.

  13. Attribute Node dialog box

  14. In the Name field, type exns:id.
  15. The database column e.EmpId is already specified in the Select Expression drop-down list, so there is no need to select it.
    • Select the Is Key? checkbox.
  16. Click OK. The ATTRIBUTE KEY node appears in the project tree.

  17. jXTransformer Query window with the ATTRIBUTE KEY node added

  18. Next, add an attribute named exns:name that will retrieve the last name of the employee from the database column e.LastName. Because this attribute will be a child of the element named empinfo, right-click the ELEMENT node named empinfo. Select Insert / Attribute node / As Select Expression. The Attribute Node dialog box appears.

  19. Attribute Node dialog box

  20. In the Name field, type exns:name.
  21. From the Select Expression drop-down list, select e.LastName.
  22. Click OK. The ATTRIBUTE node appears in the project tree.


jXTransformer Query window with the ATTRIBUTE node added

Now, you have constructed the parent query and can construct the nested child query as described in the next section.

Constructing the Child Query in the Builder

  1. To construct the child query, create another Base SQL Query that is a child of the element named empinfo. To do this, right-click the ELEMENT node named empinfo. Select Insert / Base SQL Query. The Base SQL Query Node dialog box appears.

  2. Base SQL Query Node dialog box

  3. Type the following Base SQL Query for the child query:
  4. SELECT

    p.Name,

    a.Task

    FROM Projects p, Assignments a

    WHERE p.ProjId=a.ProjId and a.EmpId=e.EmpId

    Remember that the Base SQL Query accomplishes the following tasks:

  5. Click OK. The Builder checks the Base SQL Query for syntax. The Base SQL Query node appears in the project tree.

  6. jXTransformer Query window with the Base SQL Query node added

    Now that you have defined which data to retrieve from the database for the child query, you can now define the XML structure, including the hierarchical relationships of the data.

    Examine the child query in our example as shown in the following code. You need to create an element that contains basic project information for the employee, including the name of the project and the task the employee worked on for that project.

    (SELECT

    xml_element('project',

    xml_attribute('name',p.Name),

    xml_attribute('task',a.Task))

    FROM Projects p, Assignments a

    WHERE p.ProjId=a.ProjId and a.EmpId=e.EmpId))

    Notice that the element named project is a parent to the following attributes:

  7. Because the element only contains child constructs, you can create an ELEMENT node named project with an empty value. To do this, right-click the Base SQL Query node, and select Insert / Element Node / Empty. The Element Node dialog box appears.

  8. Element Node dialog box

  9. In the Name field, type project.
  10. Click OK. The ELEMENT node appears in the project tree.

  11. jXTransformer Query window with the ELEMENT node added

  12. Now, add an attribute named name that will retrieve the name of the project from the database column p.Name. Because this attribute will be a child of the element named project, right-click the ELEMENT node named project. Select Insert / Attribute node / As Select Expression. The Attribute Node dialog box appears.

  13. Attribute Node dialog box

  14. In the Name field, type name.
  15. The database column p.Name is already selected in the Select Expression drop-down list, so there is no need to select it.
  16. Click OK. The ATTRIBUTE node appears in the project tree.

  17. jXTransformer Query window with the ATTRIBUTE node added

  18. Next, add an attribute named task that retrieves the tasks the employee worked on from the database column a.Task. Because this attribute will be a child of the element named project, right-click the ELEMENT node named project. Select Insert / Attribute Node / As Select Expression. The Attribute Node dialog box appears.

  19. Attribute Node dialog box

  20. In the Name field, type task.
  21. In the Select Expression drop-down list, select a.Task.
  22. Click OK. The ATTRIBUTE node appears in the project tree.

  23. jXTransformer Query window with the ATTRIBUTE node added

  24. Save the jXTransformer query by selecting File / Save Project.

You have completed the part of the query that specifies which data will be retrieved and defines the XML structure of the resulting XML document.

If you want to see what the jXTransformer query looks like using the jXTransformer syntax, switch to Text view in the Builder by selecting the Text View tab. If the jXTransformer query you created is correct syntactically, the Builder allows you to switch from Tree view to Text view or the reverse.

jXTransformer Query window in text view

To learn how to specify document-level constructs within the query, you can continue with the next section. Or, you can specify document-level constructs within the Java application (see "Using a jXTransformer Query in a Java Application" for instructions).

Specifying Document-Level Constructs in the jXTransformer Query

If the Builder project you created for the jXTransformer query in the previous section is not already open, open it by selecting File / Open Project. Navigate to the project file named example4.jxb and select it. The project appears either in Text view or Tree view, depending on the Builder view in which it was last saved. If the project appears in Text view, switch to Tree view by selecting the Tree View tab on the jXTransformer Statement window.

jXTransformer Query window in tree view

Adding the Root Element

  1. Insert a root element by selecting Insert / Document Header. A ROOT ELEMENT node is created in the project tree with a default root element name of jxtr-result.

  2. jXTransformer Query window with the ROOT ELEMENT node added

  3. Because we will name the root element exns:example4, right-click the ROOT ELEMENT node and select Edit. The Root Element Node dialog box appears with jxtr-result in the Name field.

  4. Root Element Node dialog box

  5. Highlight jxtr-result In the Name field, and type exns:example4.
  6. Click OK. The name of the ROOT ELEMENT node in the project tree is changed to exns:example4.


jXTransformer Query window with the ROOT ELEMENT node changed

Notice that the root element contains an attribute named rootatt1and two namespace definitions. The first namespace definition defines the default namespace; the second defines a namespace with a prefix ID of exns.

Adding an Attribute to the Root Element

  1. Add an attribute named rootatt1 to the root element. Select the ROOT ELEMENT node, and select Insert / Attribute Node / as Constant. The Attribute Node dialog box appears.

  2. Attribute Node dialog box

  3. In the Name field, type rootatt1.
  4. In the Value field, type example4.
  5. Click OK. The ATTRIBUTE node appears in the project tree.


jXTransformer Query window with the ATTRIBUTE node added

Add Namespaces to the Root Element

  1. Define the default namespace associated with the root element. Select the ROOT ELEMENT node, and select Insert / Namespace Node. The Namespace Node dialog box appears.

  2. Namespace Node dialog box

  3. Because we are defining the default namespace, there is no prefix. Leave the Prefix field blank.
  4. In the Namespace URI, type http://www.jxtrdemo/default.
  5. Click OK. The NAMESPACE node appears in the project tree.

  6. jXTransformer Query window with the NAMESPACE node added

  7. Next, define a namespace associated with the root element with a prefix ID of exns. Select the ROOT ELEMENT node, and select Insert / Namespace Node. The Namespace Node dialog box appears.

  8. Namespace Node dialog box

  9. In the Prefix field, type exns.
  10. In the Namespace URI field, type http://www.jxtrdemo/example4.
  11. Click OK. The NAMESPACE node appears in the project tree.


jXTransformer Query window with the NAMESPACE node added

Adding a Comment

  1. Next, add a comment to the document header. Select the project node, and select Insert / Comment. The Comment Node dialog box appears.

  2. Comment Node dialog box

  3. In the Comment field, type jxtr Example4.
  4. Click OK. The COMMENT node appears in the project tree.


jXTransformer Query window with the COMMENT node added

Adding a Reference to an External DTD

  1. Add a reference to an external DTD named example4.dtd. Select the project node, and select Insert / External DTD. The External DTD Node dialog box appears.

  2. External DTD Node dialog box

  3. Because you are specifying a private external DTD, leave the Public Identifier field blank.
  4. In the URI field, type example4.dtd.
  5. Click OK. The EXTERNAL DTD node appears in the project tree.


jXTransformer Query window with the EXTERNAL DTD node added

Adding a Processing Instruction

  1. Add a processing instruction that specifies an XSL stylesheet named example4.xsl. Select the project node, and select Insert / Processing Instruction. The Processing Instruction Node dialog box appears.

  2. Processing Instruction Node dialog box

  3. In the Processing Instruction Target field, type xml-stylesheet.
  4. In the Processing Instruction field, type " text/xsl" href="file://example4.xsl".
  5. Click OK. The PROCESSING INSTRUCTION node appears in the project tree.


jXTransformer Query window with the PROCESSING INSTRUCTION node added

Executing the jXTransformer Query

You have now specified all the document-level constructs in our jXTransformer query example within the query. If you want to see what the XML results would look like, you can execute the query using the Builder.

NOTE: To execute the query and return valid results, you must have created the demo database tables as explained in the README in the examples directory in your Connect for SQL/XML installation directory.

To execute the jXTransformer query:

  1. Select Project / Execute Statement. If you are not connected to the database, you must make a JDBC connection. The Open JDBC Connection dialog box appears.

  2. Open JDBC Connection dialog box

    The Connection URL option is selected by default. If you want to connect to the database using:

    Then, continue with the next step.

  3. Because the jXTransformer query contains parameter markers, the Query Parameters dialog box appears, prompting you for the parameter values.

  4. Query Parameters dialog box

    In the first Value field, type 1and in the second Value field, type 5. Then, click OK.

    The Execute Statement window appears.


    Execute Query dialog box

  5. Click OK to execute the query. The query results appear in a separate window.


Query Results window

Continue with the next section to learn how to code the jXTransformer query in a Java application.

Using a jXTransformer Query in a Java Application

You can cut and paste the jXTransformer query from the Text view of the Builder into a Java application. For more information about how to use a query in a Java application, refer to the following examples:

Example A: Document-Level Constructs in the jXTransformer Query

The code example in this section can be found in the JXTRExample4.java file in the examples/src/examples/jxtrapi directory in your Connect for SQL/XML installation directory.

The following code example performs the following tasks:

jxtrQ.append ( "

and ends with:

");

Also, notice that quotes in a Java string constant must be preceded by the Java escape character \, for example:

jxtrQ.append ( " xml_pi('xml-stylesheet', ");

jxtrQ.append ( " 'type=\"text/xsl\"
href=\"file://example4.xsl\"'), ");

setInt (paramIx, paramValue)

where paramIxidentifies the parameter and paramValuesets the value of the parameter. So, you can see that in our example:

JXTRQuery.setInt ( 1, 1 );

sets the value of the first parameter marker to 1, and:

JXTRQuery.setInt ( 2, 5 );

sets the value of the second parameter marker to 5.

TIP: You also can generate a DTD that describes the resulting XML using the Builder.

import java.io.OutputStreamWriter; 
import java.sql.*; 
 
import com.ddtek.jxtr.*; 
import examples.*; 
 
public class JXTRExample4 extends Example 
{ 
 
    /** 
     * Executes the 'JXTRExample4' example 
     */ 
    public void execute() throws Exception 
    { 
        // Output example description 
        System.out.println( "==============================" ); 
        System.out.println( "= JXTR Example4 demonstrates =" ); 
        System.out.println( "==============================" ); 
        System.out.println( "  (a) Creating XML documents that contain 
document level processing instructions," ); 
        System.out.println( "      comments, namespaces, an external DTD 
reference and a root element with attributes." ); 
        System.out.println( "  (b) Use of a bind marker in a jxtr statement." 
); 
        System.out.println( "  (c) Create a DTD describing the XML that 
results from executing the jxtr query." ); 
 
        // Load properties from the resource 
        loadProperties(); 
 
        // Create JDBC connection 
        connectWithStandardJDBC(); 
 
        // Build jxtr query 
        StringBuffer jxtrQ = new StringBuffer(); 
        jxtrQ.append ( "xml_document( "); 
        jxtrQ.append ( "  xml_comment('jxtr Example4' ), "); 
        jxtrQ.append ( "  xml_external_dtd('example4.dtd' ), "); 
        jxtrQ.append ( "  xml_pi('xml-stylesheet', "); 
        jxtrQ.append ( "         'type=\"text/xsl\" href=
\"file://example4.xsl\"'), "); 
        jxtrQ.append ( "  xml_element('exns:example4', "); 
        jxtrQ.append ( "    xml_attribute('rootatt1','example4'), "); 
        jxtrQ.append ( "    xml_namespace('http://www.jxtrdemo/default'),     
"); 
        jxtrQ.append ( "    
xml_namespace('exns','http://www.jxtrdemo/example4'), "); 
        jxtrQ.append ( "    select "); 
        jxtrQ.append ( "     xml_element('empinfo', "); 
        jxtrQ.append ( "       xml_attribute('exns:id',e.EmpId ), "); 
        jxtrQ.append ( "       xml_attribute('exns:name',e.LastName)) "); 
        jxtrQ.append ( "    from Employees e where e.EmpId between ? and ?)) 
"); 
 
        // Construct new JXTRQuery object 
        JXTRQuery JXTRQuery = new JXTRQuery ( conn, new String ( jxtrQ ) ); 
        // Set bind marker value 
        JXTRQuery.setInt ( 1, 1 ); 
        JXTRQuery.setInt ( 2, 5 ); 
 
        // Create dtd  
        java.io.FileWriter dtdFile = new java.io.FileWriter ( "example4.dtd" 
); 
        JXTRQuery.generateDTD ( dtdFile ); 
        dtdFile.close(); 
 
        // Output result header 
        System.out.println( "------------" ); 
        System.out.println( "Query result" ); 
        System.out.println( "------------" ); 
 
        // Execute 
        OutputStreamWriter systemOutWriter = new OutputStreamWriter ( 
System.out ); 
        boolean outputDocHeader = true; 
        JXTRQuery.executeWriter ( systemOutWriter, outputDocHeader, 
systemOutWriter.getEncoding ( ), 2 ); 
 
        // Close JDBC connection 
        disconnect(); 
 
    } 
 
    /** 
     * Main method. 
     */ 
    public static void main ( String[] args ) throws Exception 
    { 
        Example thisDemo = new JXTRExample4();     
        thisDemo.execute(); 
    } 
 
 
} 

Example B: Document-Level Constructs in the jXTransformer API

The following code example can be found in the JXTRExample5.java file in the examples/src/examples/jxtrapi directory in your Connect for SQL/XML installation directory.

The following code example performs the following tasks:

jxtrQ.append ( "

and ends with

");

JXTRQuery.setInt ( 1, 6 );

sets the value of the first parameter marker to 6, and:

JXTRQuery.setInt ( 2, 10 );

sets the value of the second parameter marker to 10.

import java.io.OutputStreamWriter; 
import java.sql.*; 
 
import com.ddtek.jxtr.*; 
import examples.*; 
 
public class JXTRExample5 extends Example 
{ 
 
    /** 
     * Executes the 'JXTRExample5' example 
     */ 
    public void execute() throws Exception 
    { 
        // Output example description 
        System.out.println( "==============================" ); 
        System.out.println( "= JXTR Example5 demonstrates =" ); 
        System.out.println( "==============================" ); 
        System.out.println( "  (a) Creating XML documents that contain 
document level processing instructions," ); 
        System.out.println( "      comments, namespaces, an external DTD 
reference and a root element with attributes." ); 
        System.out.println( "  (b) How to accomplish this through the jxtr 
API." ); 
        System.out.println( "  (c) Use of a bind marker in a jxtr statement." 
); 
 
        // Load properties from the resource 
        loadProperties(); 
 
        // Create JDBC connection 
        connectWithStandardJDBC(); 
 
        // Build jxtr query 
        StringBuffer jxtrQ = new StringBuffer(); 
        jxtrQ.append ( "select "); 
        jxtrQ.append ( "  xml_element('empinfo', "); 
        jxtrQ.append ( "  xml_attribute('exns:id',e.EmpId ), "); 
        jxtrQ.append ( "  xml_attribute('exns:name',e.LastName)) "); 
        jxtrQ.append ( "from Employees e where e.EmpId between ? and ? "); 
 
        // Construct new JXTRQuery object 
        JXTRQuery JXTRQuery = new JXTRQuery ( conn, new String ( jxtrQ ) ); 
        // Set document level comment,dtd reference and pi 
        JXTRQuery.addDocumentComment ( "jxtr Example5" ); 
        JXTRQuery.setExternalDTD ( "example5.dtd" ); 
        JXTRQuery.addDocumentPI ( "xml-stylesheet", "type=\"text/xsl\" href=
\"file://example5.xsl\""); 
        // Set root element name, root attribute and namespaces 
        JXTRQuery.setRootTag ( "exns:example5" ); 
        JXTRQuery.addRootAttribute ( "rootatt1", "example5" ); 
        JXTRQuery.addRootNameSpace ( "http://www.jxtrdemo/default" ); 
        JXTRQuery.addRootNameSpace ( "exns", "http://www.jxtrdemo/example5" 
); 
        // Set bind marker value 
        JXTRQuery.setInt ( 1, 6 ); 
        JXTRQuery.setInt ( 2, 10 ); 
 
        // Output result header 
        System.out.println( "------------" ); 
        System.out.println( "Query result" ); 
        System.out.println( "------------" ); 
 
        // Execute 
        OutputStreamWriter systemOutWriter = new OutputStreamWriter ( 
System.out ); 
        boolean outputDocHeader = true; 
        JXTRQuery.executeWriter ( systemOutWriter, outputDocHeader, 
systemOutWriter.getEncoding ( ), 2 ); 
 
        // Close JDBC connection 
        disconnect(); 
 
    } 
 
    /** 
     * Main method. 
     */ 
    public static void main ( String[] args ) throws Exception 
    { 
        Example thisDemo = new JXTRExample5();     
        thisDemo.execute(); 
    } 
 
 
} 

PREVNEXTINDEX