dleslie 00/02/02 08:04:44
Modified: docs extensions.xml
Log:
Editorial revisions
Revision Changes Path
1.4 +36 -23 xml-xalan/docs/extensions.xml
Index: extensions.xml
===================================================================
RCS file: /home/cvs/xml-xalan/docs/extensions.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- extensions.xml 2000/02/01 22:06:30 1.3
+++ extensions.xml 2000/02/02 16:04:43 1.4
@@ -27,7 +27,7 @@
</s2><anchor name="supported-lang"/>
<s2 title="Supported languages">
<p>&xslt4j; uses the Bean Scripting Framework (BSF), an architecture for
incorporating scripting into Java applications and applets. BSF allows an
application to take advantage of scripting while being independent of any
specific scripting language. To date, we have tested extensions implemented in
Java and JavaScript. Other languages with BSF support appear in the table
below.</p>
-<p>BSF requires two JAR files on the classpath: bsf.jar and bsfengines.jar.
These two JAR files are shipped with &xslt4j;, and that is all that is required
for Java extensions. The additional JAR files or DLLs required to support
extensions in other languages are listed in the table below. These files are
available from the sources indicated and are not shipped with &xslt4j;.</p>
+<p>BSF requires two JAR files on the class path: bsf.jar and bsfengines.jar.
These two JAR files are shipped with &xslt4j;, and that is all that is required
for Java extensions. The additional JAR files or DLLs required to support
extensions in other languages are listed in the table below. These files are
available from the sources indicated and are not shipped with &xslt4j;.</p>
<table>
<tr>
<td><em>Language</em></td>
@@ -75,10 +75,10 @@
</table>
</s2><anchor name="basic-pattern"/>
<s2 title="The basic pattern">
-<p>The stylesheet below uses an extension element and an extension function
to transform each <deadline numdays="<ref>n</ref>"/> element in the XML
source into a statement indicating the date by which a customer should receive
a response to an enquiry.</p>
+<p>Let's examine a simple example. The stylesheet below uses an extension
element and an extension function to transform an element in the XML source
into a statement in the output indicating the date by which a customer can
expect to a response to a given enquiry.</p>
-<p>The extension element contains a multiplier attribute, which is used to
set a variable in the extension. The extension function computes the deadline,
that is the current date plus numdays * multiplier. So for <deadline
numdays="3"/> (in the XML source) and <timelapse multiplier="2"/> (in
the stylesheet), the extension computes a deadline 6 days from now, and the
stylesheet template transform the deadline element into a string along the
lines of <code><p>We have received your enquiry and will respond by April
29, 2000 12:07:16 PM EST.</p></code></p>
-<note>In case your noticed, the extension function could include both
numdays and multiplier as arguments, thus bypassing the need for the extension
element. The purpose here is to illustrate the usage pattern for both extension
elements and extension functions.</note>
+<p>The source element contains a numdays attribute. The extension element
contains a multiplier attribute, which is used to set a variable in the
extension. The extension function computes the deadline, that is the current
date plus numdays * multiplier. So for <deadline numdays="3"/> (in the
XML source) and <timelapse multiplier="2"/> (in the stylesheet), the
extension computes a deadline 6 days from now, and the stylesheet template
transform the deadline element into a string along the lines of
<code><p>We have received your enquiry and will respond by April 29, 2000
12:07:16 PM EST.</p></code></p>
+<note>The extension function could include both numdays and multiplier as
arguments, thus bypassing the need for the extension element, but the purpose
here is to illustrate the usage pattern for both extension elements and
extension functions.</note>
<p>As you review this stylesheet, please note the following:</p>
<ol>
<li>The declaration of the Xalan lxslt namespace, which provides
support for the component and
@@ -135,7 +135,7 @@
</source>
</s2><anchor name="setup-runtime"/>
<s2 title="Setting up the runtime environment">
-<p>To run the preceding example, bsf.jar, bsfengines.jar, and js.jar must be
on the class path. Remember that bsf.jar and bsfengines.jar must be on the
class path to run any extension. For extensions implemented in a scripting
language, see the requirements in <link anchor="supported-lang">Supported
languages</link>.</p>
+<p>To run the preceding example, bsf.jar, bsfengines.jar, and js.jar must be
on the class path. Remember that bsf.jar and bsfengines.jar must be on the
class path to run any extension. For extensions implemented in a scripting
language, see the additional requirements in <link
anchor="supported-lang">Supported languages</link>.</p>
</s2><anchor name="basic-syntax"/>
<s2 title="Syntax">
<p>You can always use the pattern illustrated above to set up and use
extension elements and extension functions. For extension functions implemented
in Java, you can also use the java namespace, described in <link
anchor="java-namespace">Alternative: using the predefined java extension
namespace</link>. Unless you are using the predefined java extension namespace,
do the following:</p>
@@ -145,13 +145,17 @@
<note>You may also use the LotusXSL alias for this namespace:
"http://xsl.lotus.com/".</note>
</s3>
<s3 title="2. Declare a unique namespace for each extension prefix">
-<p><br/><code>xmlns:<ref>prefix</ref>:<ref>URI</ref></code></p>
+<p><br/><code>xmlns:<ref>prefix</ref>=<ref>URI</ref></code></p>
<p>The <ref>prefix</ref> identifies the namespace, and <ref>URI</ref> is one
of the following:</p>
<ul>
- <li>An arbitrary (but unique) string.<br/><br/></li>
+ <li>An arbitrary (but unique) string.<br/>
+ Example: <code>xmlns:ext1="xyz"</code><br/><br/></li>
<li><code>[class:]<ref>FQCN</ref></code><br/>
- where <ref>FQCN</ref> is a Java fully qualified class name. If the
extension only involves static class method calls (no instance constructors or
instance method calls) precede the class name with
<code>class:</code>.<br/><br/></li>
- <li>The file name or URL for another document that contains the
xslt:component element.</li>
+ where <ref>FQCN</ref> is a Java fully qualified class name. If the
extension only involves static class method
+ calls (no instance constructors or instance method calls) precede the
class name with <code>class:</code>.<br/>
+ Example: <code>xmlns:ext2="java.util.Hashtable"</code><br/><br/></li>
+ <li>The file name or URL for another document that contains the
xslt:component element.<br/>
+ Example: <code>xmlns:ext3="my-component.txt"</code></li>
</ul>
<p>If the stylesheet contains an xslt:component element with a prefix
attribute set to the extension prefix, the only function of the URI is to
provide a unique namespace. If the stylesheet does not contain an
xslt:component, the URI must identify a Java class or a document containing the
xslt:component.</p>
</s3>
@@ -180,7 +184,9 @@
<s3 title="5. Set up the lxslt:script element">
<p>In each xslt:component, you must include an lxslt:script element. If the
extension is implemented in Java:</p>
<p><code><lxslt:script lang="javaclass"
src="<ref>[class:]FQCN</ref>"/></code></p>
-<p>where <ref>FQCN</ref> is the fully qualified class name. If the extension
only involves static class method calls (no instance constructors or instance
method calls) precede the class name with <code>class:</code>.</p>
+<p>where <ref>FQCN</ref> is the fully qualified class name. If the extension
only involves static class method calls (no instance constructors or instance
method calls) precede the class name with <code>class:</code>.<br/>
+Example: <code><lxslt:script lang="javaclass"</code><br/>
+<code> src="java.util.Hashtable"/></code></p>
<p>If the extension is implemented in JavaScript:</p>
<p><code><lxslt:script lang="javascript" ></code><br/>
<code> <!--The implementation script--></code><br/>
@@ -214,7 +220,11 @@
<code> org.w3c.dom.Element
extensionElement)</code></p>
<p>where <ref>Type</ref> designates the return type and <ref>element</ref>
is the local part of the extension element name (the element name without the
namespace prefix).</p>
<p>If the extension element is implemented in a loosely typed scripting
language, such as JavaScript, the arguments and return value are untyped.</p>
-<p><em>Caution:</em> The value returned by an extension element is placed in
the transformaiton result. If you are not interested in a return value, use a
public void Java method or return null from a scripting language function.</p>
+<p><em>Caution:</em> The value returned by an extension element is placed in
the transformation result. If you are not interested in a return value, use a
public void Java method or return null from a scripting language function.</p>
+<p>Java example: <code>public void myElement</code><br/>
+<code> (org.apache.xalan.xslt.XSLProcessorContext,
</code><br/>
+<code> org.w3c.dom.Element
extensionElement)</code></p>
+<p>JavaScript example: <code>function myElement(xslProcContext,
element)</code></p>
</s3>
<s3 title="The Redirect extension">
<p>The Redirect extension (<jump href =
"apidocsorg/apache/xalan/xslt/extensions/Redirect.html">org.apache.xalan.xslt.extensions.Redirect</jump>)
is shipped with &xslt4j; (more extensions are on the way!).</p>
@@ -325,25 +335,28 @@
<s3 title="Extension function Java calls">
<p>Use the following syntax to instantiate Java objects and to call
methods:</p>
<p><code><ref>prefix</ref>:<ref>FQCN</ref>.new (<ref>args</ref>)</code></p>
+<p>where <ref>prefix</ref> is the extension namespace prefix and
<ref>FQCN</ref> is the fully qualified class name of which a new instance is to
be created with the <ref>args</ref> constructor arguments (if any).<br/>
+Example: <code>variable myHash</code><br/>
+<code> select"my-ext:java.util.Hashtable.new()"</code></p>
-<p>where <ref>prefix</ref> is the extension namespace prefix and
<ref>FQCN</ref> is the fully qualified class name of which a new instance is to
be created with the <ref>args</ref> constructor arguments (if any).</p>
-
<p><code><ref>prefix</ref>:<ref>FQCN.methodName</ref>
(<ref>args</ref>)</code></p>
-
-<p>where <ref>FQCN</ref> is the fully qualified class name whose static
method <ref>methodName</ref> is to be invoked using the <ref>args</ref>
arguments. </p>
+<p>where <ref>FQCN</ref> is the fully qualified class name whose static
method <ref>methodName</ref> is to be invoked using the <ref>args</ref>
arguments.<br/>
+Example: <code>variable new-pop</code><br/>
+<code> select="my-ext:java.lang.Integer.valueOf(string(@population)"</code></p>
<p><code><ref>prefix</ref>:<ref>methodName</ref> (<ref>object</ref>,
<ref>args</ref>)</code></p>
-
-<p>where <ref>methodName</ref> is the name of the method to invoke on
<ref>object</ref> with the <ref>args</ref> arguments.</p>
+<p>where <ref>methodName</ref> is the name of the method to invoke on
<ref>object</ref> with the <ref>args</ref> arguments.<br/>
+Example: <code>variable old-pop </code><br/>
+<code> select="my-ext:put($myHash,
string(@region), $new-pop)"</code></p>
</s3>
<s3 title="Passing Nodes to java">
-<p>Please keep in mind that <em>all</em> LocationPath expressions return a
node-set, even if the expression only returns a single attribute or a text node
(node-sets with one member). You can use the XSLT string() function to convert
a node-set value to string, and the number() function to convert a node-set
value to number (a double).</p>
-<p>If you want to pass a node-list to an extension function, set up a Java
method to accept an
+<p>Please keep in mind that <em>all</em> LocationPath expressions return a
node-set, even if the expression only returns a single attribute or a text node
(node-sets with one member). You can use the XSLT string() function (as in the
syntax examples above) to convert a node-set value to string, and the number()
function to convert a node-set value to number (a double).</p>
+<p>If you want to pass a node-set to an extension function, set up a Java
method to accept an
org.w3c.dom.NodeList (or an org.apache.xalan.xpath.MutableNodeList, which
extends NodeList, if you want to modify the nodes).</p>
<p>Suppose, for example, you have a myExtensions.ProcessNodes class with the
following doSomething method:</p>
<p><code>public static void doSomething(org.w3c.dom.NodeList
nList)</code></p>
-<p>Assuming you set up this extension in the node-ext namespace, any of the
following extension calls from a stylesheet are syntatically possible:</p>
+<p>Assuming you set up this extension in the node-ext namespace, any of the
following extension calls from a stylesheet are syntactically possible:</p>
<p><code><!--Process the current node--></code><br/>
<code>node-ext:MyExtensions.ProcessNodes.doSomething(.)</code></p>
<p><code><!--Process all nodes in current context--></code><br/>
@@ -372,7 +385,7 @@
<s3 title="Use the java namespace when you make extension function calls">
<p>Use "java" as the prefix with the syntax described in <link
anchor="ext-func-calls">Extension function Java calls</link>.</p>
<p>That is all. You do not need to set an extension-element-prefixes
attribute, and you do not include an xslt:component element. Given the absence
of the lxslt:component element, you cannot use the function-available method to
determine at runtime whether a Java method call is actually available. </p>
-<p>Using the java namespace clearly involves less setup than using your own
namespace, as long as these restrictions are not a probleem. Remember that you
always have the option of setting up your own namespace and extra overhead is
really minimal.</p>
+<p>Using the java namespace clearly involves less setup than using your own
namespace, as long as these restrictions are not a problem. Remember that you
always have the option of setting up your own namespace and extra overhead is
really minimal.</p>
</s3><anchor name="ex-java-namespace"/>
<s3 title="Example: Formatting a date">
<p>This example uses extension functions to call the SimpleDateFormat class
and the IntDate class. IntDate uses String arguments to set up a Date
object:</p>
@@ -386,7 +399,7 @@
// Date(int, int, int) has been deprecated, so use Calendar to
// set the year, month, and day.
Calendar c = Calendar.getInstance();
- // Cast each argument to int.
+ // Convert each argument to int.
c.set(Integer.parseInt(year),Integer.parseInt(month),Integer.parseInt(day));
return c.getTime();
}
@@ -440,7 +453,7 @@
<anchor name="ex-java"/>
<s3 title="Java implementation">
<p>MyCounter.java</p>
-<source>mport java.util.*;
+<source>Import java.util.*;
public class MyCounter {
Hashtable counters = new Hashtable ();