http://xml.apache.org/http://www.apache.org/http://www.w3.org/

What's New
DTM
XSLTC Translets

Overview
Getting Started

FAQs

Sample Apps
Command Line

Usage Patterns

TrAX
API (Javadoc)

Extensions
Extensions Library

Release Notes

Xalan 2 Design
XSLTC Design

Bugs
Testing

Credits
XSLTC Credits

Introduction
 

Extension elements and functions provide a powerful mechanism for extending and simplifying what you can do with an XLST processor like Xalan. With input and contributions from the XML open-source developer community, we are working on placing the most useful extensions in an extensions library distributed with Xalan-Java. If you have ideas and/or contributions you would like to make, please email us at the Xalan Development Mailing List.


Xalan namespace
 

Where it makes sense, we are placing the new Xalan extensions in the org.apache.xalan.lib.Extensions class and we have defined a namespace for this class:

     http://xml.apache.org/xalan

If you are calling Xalan-Java-supplied extensions, we recommend that you define this namespace in your stylesheet element, and call the extension using the namespace prefix that you have associated with that namespace. That way, if we later reorganize how the Xalan-Java-supplied extensions are stored, you won't have to modify your stylesheet.

For an example that uses this namespace, see Example with the nodeset extension function.


Redirect
 

A standard XSL transformation involves an XSL stylesheet, an XML source tree, and the transformation result tree. The transformation sends the entire result to a single org.apache.trax.Result object.

The Redirect extension (org.apache.xalan.xslt.extensions.Redirect) supplies three extension elements that you can use to redirect portions of your transformation output to multiple files: <open>, <write>, and <close>. If you use the <write> element alone, the extension opens a file, writes to it, and closes the file immediately. If you want explicit control over the opening and closing of files, use <write> in conjunction with the <open> and <close> elements.

Each of these elements includes a file attribute and/or a select attribute to designate the output file. The file attribute takes a string, so you can use it to directly specify the output file name. The select attribute takes an XPath expression, so you can use it to dynamically generate the output file name. If you include both attributes, the Redirect extension first evaluates the select attribute, and falls back to the file attribute if the select attribute expression does not return a valid file name.

Example with the Redirect extension
 

Suppose you are outputting the bulk of your result tree to one file, but you want to output the transformation of all <foo> elements and their children to another file. The following example illustrates the basic structure of the XML source:

<?xml version="1.0"?> 
<doc>
  <foo file="foo.out">
    Testing Redirect extension:
      <bar>A foo subelement text node</bar>
  </foo>
  <main>
    Everything else
  </main>  
</doc>

This stylesheet redirects part of the output to a secondary file:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0"
    xmlns:lxslt="http://xml.apache.org/xslt"
    xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"
    extension-element-prefixes="redirect">

  <xsl:template match="/">
    <standard-out>
      Standard output:
      <xsl:apply-templates/>
    </standard-out>
  </xsl:template>
  
  <xsl:template match="main">
    <main>
      <xsl:apply-templates/>
    </main>
  </xsl:template>
  
  <xsl:template match="/doc/foo">
    <redirect:write select="@file">
      <foo-out>
        <xsl:apply-templates/>
      </foo-out>
    </redirect:write>
  </xsl:template>
  
  <xsl:template match="bar">
    <foobar-out>
      <xsl:apply-templates/>
    </foobar-out>
  </xsl:template>
  
</xsl:stylesheet>

The standard output is:

<?xml version="1.0" encoding="UTF-8"?>
<standard-out>
  Standard output:
  <main>
    Everything else.
  </main>
<standard-out>

The output redirected to foo.out is:

<?xml version="1.0" encoding="UTF-8"?>
<foo-out>
    Testing Redirect extension:
    <foobar-out>foo subelement text node</foobar-out>
  </foo-out>

For more information on using the Redirect extension to send output to multiple files, examine the SimpleRedirect sample and see the Redirect class Javadoc.



nodeset
 

Implemented in org.apache.xalan.lib.Extensions,
nodeset (result-tree-fragment) casts a result tree fragment into a node-set.

NoteWhen you bind a variable to a template, rather than to the value generated by a select expression, the data type of the variable is result tree fragment. For more information, see Result Tree Fragments.
Example with the nodeset extension function
 

The following stylesheet uses the nodeset extension function to cast a result tree fragment into a node-set that can then be navigated in standard XPath manner. It uses the http://xml.apache.org/xalan namespace to provide access to the nodeset() method in xml.apache.xalan.lib.Extensions.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:xalan="http://xml.apache.org/xalan"
                exclude-result-prefixes="xalan">
<xsl:template match="/">
  <out>
	  <xsl:variable name="rtf">
      <docelem>
        <elem1>
          <elem1a>ELEMENT1A</elem1a>
          <elem1b>,ELEMENT1B</elem1b>
        </elem1>
        <elem2>
          <elem2a>ELEMENT2A</elem2a>
        </elem2>
      </docelem>
    </xsl:variable>     
      <xsl:for-each select="xalan:nodeset($rtf)/docelem//*">
        <xsl:value-of select="name(.)"/><xsl:text>,</xsl:text>
      </xsl:for-each>
  </out>
</xsl:template> 
</xsl:stylesheet>

The output of running this stylesheet (with any XML input source) is a comma-delimited list of the element names in the node-set
  <out>elem1,elem1a,elem1b,elem2,elem2a</out>

NoteFor illustration purposes, the preceding stylesheet pays no attention to the structure and content of the XML input document. Instead, it processes the template (in the stylesheet) bound to the variable named rtf.


intersection
 

Implemented in org.apache.xalan.lib.Extensions,
intersection (node-set1, node-set2) function returns a node-set with all nodes that are in ns1 and in ns2 .


difference
 

Implemented in org.apache.xalan.lib.Extensions,
difference(node-set1, node-set2) returns a node-set with the nodes in node-set1 and not in node-set2.


distinct
 

Implemented in org.apache.xalan.lib.Extensions,
distinct (node-set) returns a node-set containing nodes with distinct string values. If more than one node in the node-set contains the same text node value, distinct only returns the first of these nodes that it finds.


hasSameNodes
 

Implemented in org.apache.xalan.lib.Extensions,
hasSameNodes(node-set1, node-set2) returns true if both node-set1 and node-set2 contain exactly the same set of nodes.


SQL library
 

[broken in Xalan-Java version 2.2.D6 -- does not work with DTM]

**Experimental** Provides extension functions for connecting to a JDBC data source, executing a query, and optionally working incrementally through a "streamable" result set. Due to a bug, caching, not streaming, is currently the default mode of operation.

NoteMany features of the SQL library, including support for connection pools, parameterized queries, caching, and added support for extracting connection information and query parameters from XML source documents exist thanks to John Gentilin (johnglinux@eyecatching.com), who has also added a number of SQL library samples.

The SQL extension use in streaming mode of a single row-set node to incrementally return a query result set is experimental. If you use streaming mode, you can only access row elements one at a time moving forward through the result set. The use of XPath expressions in your stylesheet, for example, that attempt to return nodes from the result set in any other manner may produce unpredictable results.

org.apache.xalan.lib.sql.XConnection provides a number of extension functions that you can use in your stylesheet.

  1. new() -- Use one of the XConnection constructors to connect to a data source, and return an XConnection object. You can use one of the constructors creates a connection pool from which stylesheets can obtain connections to a datasource. To support connction pools, SQL library includes a ConnectionPool interface and a implementation: DefaultConnectionPool. You can also provide your own ConnectionPool implementation.

  2. query() -- Use the XConnection object query() method to return a "streamable" result set in the form of a row-set node. Work your way through the row-set one row at a time. The same row element is used over and over again, so you can begin "transforming" the row-set before the entire result set has been returned.

  3. pquery(), addParameter(), addParameterFromElement(), clearParameters() -- Use the XConnection pquery() method in conjunction with these other methods to set up and execute parameterized queries.

  4. Use disableCacheNodes() to use streaming node, and enableCacheNodes() to cache the query result set.

  5. close() -- Use the XConnection object close() method to terminate the connection.

The query() and pquery() extension functions return a Document node that contains (as needed) an array of column-header elements, a single row element that is used repeatedly, and an array of col elements. Each column-header element (one per column in the row-set) contains an attribute (ColumnAttribute) for each of the column descriptors in the ResultSetMetaData object. Each col element contains a text node with a textual representation of the value for that column in the current row.

Setting up a connection
 

You can place connection information (JDBC driver, datasource URL, and usually user ID and password) in stylesheets or in XML source documents.

The following stylesheet fragment uses stylesheet parameters to designate a JDBC driver and datasource. The default parameter values can be overridden with runtime parameter values.

<xsl:param name="driver" select="'org.enhydra.instantdb.jdbc.idbDriver'"/>
<xsl:param name="datasource" select="'jdbc:idb:../../instantdb/sample.prp'"/>
<xsl:param name="query" select="'SELECT * FROM import1'"/>

You can also obtain connection information from the XML source document that you use for the transformationl. Suppose you have the following DBINFO nodeset in an XML document:

<DBINFO>
  <dbdriver>org.enhydra.instantdb.jdbc.idbDriver</dbdriver>
  <dburl>jdbc:idb:../../instantdb/sample.prp</dburl>
  <user>jbloe</user>
  <password>geron07moe</password>
</DBINFO>

In the stylesheet, you can extract this information as follows:

<xsl:stylesheet version 1.0
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:sql="org.apache.xalan.lib.sql.XConnection"
     extension-element-prefixes="sql">
  <xsl:param name="cinfo" select="//DBINFO"/>
  <xsl:variable name="db" select="sql:new($cinfo)"/>
....

For an example of both approaches, see Basic Connection samples.

You can also create a named connection pool that is maintained external to Xalan-Java.

import org.apache.xalan.lib.sql.DefaultConnectionPool;
import org.apache.xalan.lib.sql.XConnectionPoolManager;
...
DefaultConnectionPool cp = new DefaultConnectionPool();
cp.setDriver("org.enhydra.instantdb.jdbc.idbDriver");
cp.setURL("jdbc:idb:../../instantdb/sample.prp");
cp.setUser("jbloe");
cp.setPassword("geron07moe");
// Start with 10 connections.
cp.setMinConnections(10);
cp.enablePool();
// Register the connection pool so stylesheets can use it.
XConnectionPoolManager pm = new XConnectionPoolManager();
pm.registerPool("extpool", cp);

A stylesheet can use this connection pool as follows:

<xsl:stylesheet version 1.0
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:sql="org.apache.xalan.lib.sql.XConnection"
     extension-element-prefixes="sql">
...
  <xsl:variable name="db" select="sql:new($driver, 'extpool')"/>

For an example, see the ExternalConnection sample.


Parameterized queries
 

To define a parameterized query, use a SQL query string with a question mark (?) for each parameter. You can provide the parameter values at runtime with stylesheet parameters or with nodes in the XML source document. For each parameter, you should also designate the SQL data type.

XConnection provides a number of addParameter() methods and an addParameterFromElement() method that you can use as extension functions to pull in the parameter values (in the order the parameters appear in the query). To execute the query and return the result set, call the pquery() method as an extension function. There are two variations of the pquery() method. The one you should ordinarily use includes as arguments the SQL query string and a string list (delimited by the space, tab, or line feeds) of parameter types. For example:

<xsl:variable name="resultset" 
        select=sql:pquery($XConnectionObj, 
                          'select * from X where Y = ? and Z = ?',
                          'int string')"/>

For a complete example, see the Parameterized query sample.


Example with SQL library
 

This example displays the result set from a table in a sample InstantDB database. It is also available as a sample application; see 6-sqllib-instantdb.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0"
                xmlns:sql="org.apache.xalan.lib.sql.XConnection"
                extension-element-prefixes="sql">
  <xsl:output method="html" indent="yes"/>
  <xsl:param name="query" select="'SELECT * FROM import1'"/>
 
  <xsl:template match="/">
    <!-- 1. Make the connection -->
    <xsl:variable name="products"
                  select="sql:new('org.enhydra.instantdb.jdbc.idbDriver',
                                'jdbc:idb:.\instantdb\sample.prp')"/>
    <HTML>
      <HEAD>
      </HEAD>
      <BODY>
        <TABLE border="1">
        <!--2. Execute the query -->
        <xsl:variable name="table" select='sql:query($products, $query)'/>
          <TR>
          <!-- Get column-label attribute from each column-header-->
          <xsl:for-each select="$table/row-set/column-header">
            <TH><xsl:value-of select="@column-label"/></TH>
          </xsl:for-each>
          </TR>
          <xsl:apply-templates select="$table/row-set/row"/>
          <xsl:text>&#10;</xsl:text>
        </TABLE>
      </BODY>
    </HTML> 
    <!-- 3. Close the connection -->
    <xsl:value-of select="sql:close($products)"/>
  </xsl:template>

  <xsl:template match="row">
        <TR>
          <xsl:apply-templates select="col"/>
        </TR>
  </xsl:template>

  <xsl:template match="col">
    <TD>
      <!-- Here is the column data -->
      <xsl:value-of select="text()"/>
    </TD>
  </xsl:template>

</xsl:stylesheet>


evaluate
 

Implemented in org.apache.xalan.lib.Extensions,
evaluate (xpath-expression) function returns the result of evaluating the xpath-expression in the current XPath expression context (automatically passed in by the extension mechanism).

Use the evaluation extension function when the value of the expression is not known until run time.


tokenize
 

Implemented in org.apache.xalan.lib.Extensions,
tokenize (tokenize-string, delimiters)
or
tokenize (tokenize-string) function returns a node-set containing one text node for each token in the tokenize-string.

The delimiters determine which characters are used to divide the tokenize-string into individual tokens. If you do not include the delimiters argument, the function uses tab (&#x09), linefeed (&#x0A), return (&#x0D), and space (&#x20) as delimiters. If tokenize-string is an empty string or contains only delimiters, the result is an empty node-set.


group and item
 

To be done. Provides efficient grouping of items with a common value.


type
 

To be done. Returns a string that represents the Schema or DTD type.


to-date
 

To be done. Takes a string as input, and returns a long value representing the date.


format-date
 

To be done. Takes a date string, and formats it according to a specification.


grep
 

To be done. Performs a grep function and returns the substring.


for-each-token
 

To be done. Tokenizes a string, treats each token as a DOM Text node, and executes the sub-template.



Copyright © 2001 The Apache Software Foundation. All Rights Reserved.