Oracle JavaServer Pages Developer's Guide and Reference Release 8.1.7 Part Number A83726-01 |
Library | Service | Contents | Index

## Standard Tag Library Framework

Standard JavaServer Pages technology allows vendors to create custom JSP tag libraries.

A tag library defines a collection of custom actions. The tags can be used directly by developers in manually coding a JSP page, or automatically by Java development tools. A tag library must be portable between different JSP container implementations.

For information beyond what is provided here regarding tag libraries and the standard JavaServer Pages tag library framework, refer to the following resources.

- Sun Microsystems JavaServer Pages Specification, Version 1.1

- Sun Microsystems Javadoc for the `javax.servlet.jsp.tagext` package, at the following Web site:

      http://java.sun.com/j2ee/j2sdkee/techdocs/api/javax/servlet/jsp/tagext/package-summary.html

  Note: Do not use the `servlet.jar` file of the Tomcat 3.1 beta servlet/JSP implementation if you are using custom tags. The constructor signature was changed for the class `javax.servlet.jsp.tagext.TagAttributeInfo`, which will result in compilation errors. Instead, use the `servlet.jar` file that is provided with OracleJSP or the production version of Tomcat 3.1.

### Overview of a Custom Tag Library Implementation

A custom tag library is imported into a JSP page using a `taglib` directive of the following general form:

    <%@ taglib uri="URI" prefix="prefix" %>

Note the following:

- The tags of a library are defined in a tag library description file, as described in "Tag Library Description Files".

- The URI in the `taglib` directive specifies where to find the tag library description file, as described in "The taglib Directive". It is possible to use URI shortcuts, as described in "Use of web.xml for Tag Libraries".

- The prefix in the `taglib` directive is a string of your choosing that you use in your JSP page with any tag from the library.

  Assume the `taglib` directive specifies a prefix `oracust`:

      <%@ taglib uri="URI" prefix="oracust" %>

  Further assume that there is a tag `mytag` in the library. You might use `mytag` as follows:

      <oracust:mytag attr1="...", attr2="..." />

  Using the `oracust` prefix informs the JSP translator that `mytag` is defined in the tag library description file that can be found at the URI specified in the above `taglib` directive.

- The entry for a tag in the tag library description file provides specifications about usage of the tag, including whether the tag uses attributes (as `mytag` does), and the names of those attributes.

- The semantics of a tag--the actions that occur as the result of using the tag--are defined in a tag handler class, as described in "Tag Handlers". Each tag has its own tag handler class, and the class name is specified in the tag library description file.

- The tag library description file indicates whether a tag uses a body.

  As seen above, a tag without a body is used as in the following example:

      <oracust:mytag attr1="...", attr2="..." />

  By contrast, a tag with a body is used as in the following example:

      <oracust:mytag attr1="...", attr2="..." >
         ...body...
      </oracust:mytag>

- A custom tag action can create one or more server-side objects that are available for use by the tag itself or by other JSP scripting elements, such as scriptlets. These objects are referred to as scripting variables.

  Details regarding the scripting variables that a custom tag uses are defined in a tag-extra-info class. This is described in "Scripting Variables and Tag-Extra-Info Classes".

  A tag can create scripting variables with syntax such as in the following example, which creates the object `myobj`:

      <oracust:mytag id="myobj" attr1="...", attr2="..." />

- The tag handler of a nested tag can access the tag handler of an outer tag, in case this is required for any of the processing or state management of the nested tag. See "Access to Outer Tag Handler Instances".

The sections that follow provide more information about these topics.

### Tag Handlers

A tag handler describes the semantics of the action that results from use of a custom tag. A tag handler is an instance of a Java class that implements one of two standard Java interfaces, depending on whether the tag processes a body of statements between a start tag and an end tag.

Each tag has its own handler class. By convention, the name of the tag handler class for a tag `abc`, for example, is `AbcTag`.

The tag library description (TLD) file of a tag library specifies the name of the tag handler class for each tag in the library. (See "Tag Library Description Files".)

A tag handler instance is a server-side object used at request time. It has properties that are set by the JSP container, including the page context object for the JSP page that uses the custom tag, and a parent tag handler object if the use of this custom tag is nested within an outer custom tag.

See "Sample Tag Handler Class: ExampleLoopTag.java" for sample code of a tag handler class.

Note: The Sun Microsystems JavaServer Pages Specification, Version 1.1 does not mandate whether multiple uses of the same custom tag within a JSP page should use the same tag handler instance or different tag handler instances--this implementation detail is left to the discretion of JSP vendors. OracleJSP uses a separate tag handler instance for each use of a tag.

#### Custom Tag Body Processing

Custom tags, like standard JSP tags, may or may not have a body. And in the case of a custom tag, even when there is a body, it may not need special handling by the tag handler.

There are three situations:

- There is no body.

  In this case, there is just a single tag, as opposed to a start tag and end tag. Following is a general example:

      <oracust:abcdef attr1="...", attr2="..." />

- There is a body that does not need special handling by the tag handler.

  In this case, there is a start tag and end tag with a body of statements in between, but the tag handler does not have to process the body--body statements are passed through for normal JSP processing only. Following is a general example:

      <foo:if cond="<%= ... %>" >
      ...body executed if cond is true, but not processed by tag handler...
      </foo:if>

- There is a body that needs special handling by the tag handler.

  In this case also, there is a start tag and end tag with a body of statements in between; however, the tag handler must process the body.

      <oracust:ghijkl attr1="...", attr2="..." >
      ...body processed by tag handler...
      </oracust:ghijkl>

#### Integer Constants for Body Processing

The tag handling interfaces that are described in the following sections specify a `doStartTag()` method (further described below) that you must implement to return an appropriate integer constant, depending on the situation. The possible return values are as follows:

- `SKIP_BODY` if there is no body or if evaluation and execution of the body should be skipped

- `EVAL_BODY_INCLUDE` if there is a body that does not require special handling by the tag handler

- `EVAL_BODY_TAG` if there is a body that requires special handling by the tag handler

#### Handlers for Tags That Do Not Process a Body

For a custom tag that does not have a body, or has a body that does not need special handling by the tag handler, the tag handler class implements the following standard interface:

- `javax.servlet.jsp.tagext.Tag`

The following standard support class implements the `Tag` interface and can be used as a base class:

- `javax.servlet.jsp.tagext.TagSupport`

The `Tag` interface specifies a `doStartTag()` method and a `doEndTag()` method. The tag developer provides code for these methods in the tag handler class, as appropriate, to be executed as the start tag and end tag, respectively, are encountered. Action processing--whatever you want the action tag to accomplish--is implemented in the `doStartTag()` method. The `doEndTag()` method would implement any appropriate post-processing. In the case of a tag without a body, essentially nothing happens between the execution of these two methods.

The `doStartTag()` method returns an integer value. For a tag handler class implementing the `Tag` interface (either directly or indirectly), this value must be either `SKIP_BODY` or `EVAL_BODY_INCLUDE` (described in "Integer Constants for Body Processing"). `EVAL_BODY_TAG` is illegal for a tag handler class implementing the `Tag` interface.

#### Handlers for Tags That Process a Body

For a custom tag with a body that requires special handling by the tag handler, the tag handler class implements the following standard interface:

- `javax.servlet.jsp.tagext.BodyTag`

The following standard support class implements the `BodyTag` interface and can be used as a base class:

- `javax.servlet.jsp.tagext.BodyTagSupport`

The `BodyTag` interface specifies a `doInitBody()` method and a `doAfterBody()` method in addition to the `doStartTag()` and `doEndTag()` methods specified in the `Tag` interface.

Just as with tag handlers implementing the `Tag` interface (described in the preceding section, "Handlers for Tags That Do Not Process a Body"), the tag developer implements the `doStartTag()` method for action processing by the tag, and the `doEndTag()` method for any post-processing.

The `doStartTag()` method returns an integer value. For a tag handler class implementing the `BodyTag` interface (directly or indirectly), this value must be either `SKIP_BODY` or `EVAL_BODY_TAG` (described in "Integer Constants for Body Processing"). `EVAL_BODY_INCLUDE` is illegal for a tag handler class implementing the `BodyTag` interface.

In addition to implementing the `doStartTag()` and `doEndTag()` methods, the tag developer, as appropriate, provides code for the `doInitBody()` method, to be invoked before the body is evaluated, and the `doAfterBody()` method, to be invoked after each evaluation of the body. (The body could be evaluated multiple times, such as at the end of each iteration of a loop.)

After the `doStartTag()` method is executed, the `doInitBody()` and `doAfterBody()` methods are executed if the `doStartTag()` method returned `EVAL_BODY_TAG`.

The `doEndTag()` method is executed after any body processing, when the end tag is encountered.

For custom tags that must process a body, the `javax.servlet.jsp.tagext.BodyContent` class is available for use. This is a subclass of `javax.servlet.jsp.JspWriter` that can be used to process body evaluations so that they can re-extracted later. The `BodyTag` interface includes a `setBodyContent()` method that can be used by the JSP container to give a `BodyContent` handle to a tag handler instance.

### Scripting Variables and Tag-Extra-Info Classes

A custom tag action can create one or more server-side objects, known as scripting variables, that are available for use by the tag itself or by other scripting elements, such as scriptlets and other tags.

Details regarding scripting variables that a custom tag defines must be specified in a subclass of the standard `javax.servlet.jsp.tagext.TagExtraInfo` abstract class. This document refers to such a subclass as a tag-extra-info class.

The JSP container uses tag-extra-info instances during translation. (The tag library description file, specified in the `taglib` directive that imports the library into a JSP page, specifies the tag-extra-info class to use, if applicable, for any given tag.)

A tag-extra-info class has a `getVariableInfo()` method to retrieve names and types of the scripting variables that will be assigned during HTTP requests. The JSP translator calls this method during translation, passing it an instance of the standard `javax.servlet.jsp.tagext.TagData` class. The `TagData` instance specifies attribute values set in the JSP statement that uses the custom tag.

This section covers the following topics:

- Defining Scripting Variables

- Scripting Variable Scopes

- Tag-Extra-Info Classes and the getVariableInfo() Method

#### Defining Scripting Variables

Objects that are defined explicitly in a custom tag can be referenced in other actions through the page context object, using the object ID as a handle. Consider the following example:

    <oracust:foo id="myobj" attr1="..." attr2="..." />

This statement results in the object `myobj` being available to any scripting elements between the tag and the end of the page. The `id` attribute is a translation-time attribute. The tag developer provides a tag-extra-info class that will be used by the JSP container. Among other things, the tag-extra-info class specifies what class to instantiate for the `myobj` object.

The JSP container enters `myobj` into the page context object, where it can later be obtained by other tags or scripting elements using syntax such as the following:

    <oracust:bar ref="myobj" />

The `myobj` object is passed through the tag handler instances for `foo` and `bar`. All that is required is knowledge of the name of the object (`myobj`).

Important: Note that `id` and `ref` are merely sample attribute names; there are no special predefined semantics for these attributes. It is up to the tag handler to define attribute names and create and retrieve objects in the page context.

#### Scripting Variable Scopes

Specify the scope of a scripting variable in the tag-extra-info class of the tag that creates the variable. It can be one of the following integer constants:

- `NESTED`--if the scripting variable is available between the start tag and end tag of the action that defines it

- `AT_BEGIN`--if the scripting variable is available from the start tag until the end of the page

- `AT_END`--if the scripting variable is available from the end tag until the end of the page

#### Tag-Extra-Info Classes and the getVariableInfo() Method

You must create a tag-extra-info class for any custom tag that creates scripting variables. The class describes the scripting variables and must be a subclass of the standard `javax.servlet.jsp.tagext.TagExtraInfo` abstract class.

The key method of the `TagExtraInfo` class is `getVariableInfo()`, which is called by the JSP translator and returns an array of instances of the standard `javax.servlet.jsp.tagext.VariableInfo` class (one array instance for each scripting variable the tag creates).

The tag-extra-info class constructs each `VariableInfo` instance with the following information regarding the scripting variable:

- its name

- its Java type

- a boolean indicating whether it is a newly declared variable

- its scope

  Important: The `getVariableInfo()` method must return a fully qualified class name, such as for a JML datatype, for the Java type of the scripting variable. (Note that primitive types are not supported.)

See "Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java" for sample code of a tag-extra-info class.

### Access to Outer Tag Handler Instances

Where nested custom tags are used, the tag handler instance of the nested tag has access to the tag handler instance of the outer tag, which may be useful in any processing and state management performed by the nested tag.

This functionality is supported through the static `findAncestorWithClass()` method of the `javax.servlet.jsp.tagext.TagSupport` class. Even though the outer tag handler instance is not named in the page context object, it is accessible because it is the closest enclosing instance of a given tag handler class.

Consider the following JSP code example:

    <foo:bar1 attr="abc" >
       <foo:bar2 />
    </foo:bar1>

Within the code of the `bar2` tag handler class (class `Bar2Tag`, by convention), you can have a statement such as the following:

    Tag bar1tag = TagSupport.findAncestorWithClass(this, Bar1Tag.class);

The `findAncestorWithClass()` method takes the following as input:

- the `this` object that is the class handler instance from which `findAncestorWithClass()` was called (a `Bar2Tag` instance in the example)

- the name of the `bar1` tag handler class (presumed to be `Bar1Tag` in the example), as a `java.lang.Class` instance

The `findAncestorWithClass()` method returns an instance of the appropriate tag handler class, in this case `Bar1Tag`, as a `javax.servlet.jsp.tagext.Tag` instance.

It is useful for a `Bar2Tag` instance to have access to the outer `Bar1Tag` instance in case `Bar2Tag` needs the value of a `bar1` tag attribute or needs to call a method on the `Bar1Tag` instance.

### Tag Library Description Files

A tag library description (TLD) file is an XML document that contains information about a tag library and about individual tags of the library. The name of a TLD file has the `.tld` extension.

A JSP container uses the TLD file in determining what action to take when it encounters a tag from the library.

A tag entry in the TLD file includes the following:

- name of the custom tag

- name of the corresponding tag handler class

- name of the corresponding tag-extra-info class (if applicable)

- information indicating how the tag body (if any) should be processed

- information about the attributes of the tag (the attributes that you specify whenever you use the custom tag)

Here is a sample TLD file entry for the tag myaction:

    <tag>
      <name>myaction</name>
      <tagclass>examples.MyactionTag</tagclass>
      <teiclass>examples.MyactionTagExtraInfo</teiclass>
      <bodycontent>JSP</bodycontent>
      <info>
          Perform a server-side action (one mandatory attr; one optional)
      </info>
      <attribute>
        <name>attr1</name>
        <required>true</required>
      </attribute>
      <attribute>
        <name>attr2</name>
        <required>false</required>
      </attribute>
    </tag>

According to this entry, the tag handler class is `MyactionTag` and the tag-extra-info class is `MyactionTagExtraInfo`. The attribute `attr1` is required; the attribute `attr2` is optional.

The `bodycontent` parameter indicates how the tag body (if any) should be processed. There are three valid values:

- A value of `empty` indicates that the tag uses no body.

- A value of `JSP` indicates that the tag body should be processed as JSP source and translated.

- A value of `tagdependent` indicates that the tag body should not be translated. Any text in the body is treated as static text.

The `taglib` directive in a JSP page informs the JSP container where to find the TLD file. (See "The taglib Directive".)

For more information about tag library description files, see the Sun Microsystems JavaServer Pages Specification, Version 1.1.

Note: In the Tomcat 3.1 servlet/JSP implementation, the TLD file `bodycontent` parameter for a given tag is not read if the tag itself (in the JSP page) has no body. It is possible, therefore, to have an invalid `bodycontent` value in your TLD file (such as `none` instead of `empty`) without realizing it. Using the file in another JSP environment, such as OracleJSP, would then result in errors.

### Use of web.xml for Tag Libraries

The Sun Microsystems Java Servlet Specification, Version 2.2 describes a standard deployment descriptor for servlets--the `web.xml` file. JSP pages can use this file in specifying the location of a JSP tag library description file.

For JSP tag libraries, the `web.xml` file can include a `taglib` element and two subelements:

- `taglib-uri`

- `taglib-location`

The `taglib-location` subelement indicates the application-relative location (by starting with "/") of the tag library description file.

The `taglib-uri` subelement indicates a "shortcut" URI to use in `taglib` directives in your JSP pages, with this URI being mapped to the TLD file location specified in the accompanying `taglib-location` subelement. (The term URI, universal resource indicator, is somewhat equivalent to the term URL, universal resource locator, but is more generic.)

Important: When a JSP application uses a `web.xml` file, you must deploy `web.xml` with the application. Treat it as a Java resource file.

Following is a sample `web.xml` entry for a tag library description file:

    <taglib>
       <taglib-uri>/oracustomtags</taglib-uri>
       <taglib-location>/WEB-INF/oracustomtags/tlds/MyTLD.tld</taglib-location>
    </taglib>

This makes `/oracustomtags` equivalent to `/WEB-INF/oracustomtags/tlds/MyTLD.tld` in `taglib` directives in your JSP pages. See "Using a Shortcut URI for the TLD File" for an example.

See the Sun Microsystems Java Servlet Specification, Version 2.2 and the Sun Microsystems JavaServer Pages Specification, Version 1.1 for more information about the `web.xml` deployment descriptor and its use for tag library description files.

Notes: Do not use the sample `web.xml` file from the Tomcat 3.1 servlet/JSP implementation. It introduces new elements that will not pass the standard DTD XML validation. Do not use the term "urn" instead of "uri" in a `web.xml` file. Some JSP implementations allow this (such as Tomcat 3.1), but using "urn" will not pass the standard DTD XML validation.

### The taglib Directive

Import a custom library into a JSP page using a `taglib` directive, of the following form:

    <%@ taglib uri="URI" prefix="prefix" %>

For the URI, you have the following options:

- Specify a shortcut URI, as defined in a `web.xml` file (see "Use of web.xml for Tag Libraries").

- Fully specify the tag library description (TLD) file name and location.

#### Using a Shortcut URI for the TLD File

Assume the following `web.xml` entry for a tag library defined in the tag library description file `MyTLD.tld`:

    <taglib>
       <taglib-uri>/oracustomtags</taglib-uri>
       <taglib-location>/WEB-INF/oracustomtags/tlds/MyTLD.tld</taglib-location>
    </taglib>

Given this example, the following directive in your JSP page results in the JSP container finding the `/oracustomtags` URI in `web.xml` and, therefore, finding the accompanying name and location of the tag library description file (`MyTLD.tld`):

    <%@ taglib uri="/oracustomtags" prefix="oracust" %>

This statement allows you to use any of the tags of this custom tag library in a JSP page.

#### Fully Specifying the TLD File Name and Location

If you do not want your JSP application to depend on a `web.xml` file for its use of a tag library, `taglib` directives can fully specify the name and location of the tag library description file, as follows:

    <%@ taglib uri="/WEB-INF/oracustomtags/tlds/MyTLD.tld" prefix="oracust" %>

The location is specified as an application-relative location (by starting with "/", as in this example). See "Requesting a JSP Page" for related discussion.

Alternatively, you can specify a `.jar` file instead of a `.tld` file in the `taglib` directive, where the `.jar` file contains a tag library description file. The tag library description file must be located and named as follows when you create the JAR file:

    META-INF/taglib.tld

Then the `taglib` directive might be as follows, for example:

    <%@ taglib uri="/WEB-INF/oracustomtags/tlds/MyTLD.jar" prefix="oracust" %>

### End-to-End Example: Defining and Using a Custom Tag

This section provides an end-to-end example of the definition and use of a custom tag, `loop`, that is used to iterate through the tag body a specified number of times.

Included in the example are the following:

- JSP source for a page that uses the tag

- source code for the tag handler class

- source code for the tag-extra-info class

- the tag library description file

#### Sample JSP Page: exampletag.jsp

Following is a sample JSP page that uses the `loop` tag, specifying that the outer loop be executed five times and the inner loop three times:

    examplestag.jsp
    <%@ taglib prefix="foo" uri="/WEB-INF/exampletag.tld" %>
    <% int num=5; %>
    <br>
    <pre>
    <foo:loop index="i" count="<%=num%>">
    body1here: i expr: <%=i%> i property: <jsp:getProperty name="i" property="value" />
      <foo:loop index="j" count="3">
      body2here: j expr: <%=j%>
      i property: <jsp:getProperty name="i" property="value" />
      j property: <jsp:getProperty name="j" property="value" />
      </foo:loop>
    </foo:loop>
    </pre>

#### Sample Tag Handler Class: ExampleLoopTag.java

Following is the source code for the tag handler class, `ExampleLoopTag`. Note the following:

- The `doStartTag()` method returns the integer constant `EVAL_BODY_TAG`, so that the tag body (essentially, the loop) is processed.

- After each pass through the loop, the `doAfterBody()` method increments the counter. It returns `EVAL_BODY_TAG` if there are more iterations left and `SKIP_BODY` after the last iteration.

      package examples;

      import javax.servlet.jsp.*;
      import javax.servlet.jsp.tagext.*;
      import java.util.Hashtable;
      import java.io.Writer;
      import java.io.IOException;
      import oracle.jsp.jml.JmlNumber;

      public class ExampleLoopTag
          extends BodyTagSupport
      {

          String index;
          int count;
          int i=0;
          JmlNumber ib=new JmlNumber();

          public void setIndex(String index)
          {
            this.index=index;
          }
          public void setCount(String count)
          {
            this.count=Integer.parseInt(count);
          }

          public int doStartTag() throws JspException {
              return EVAL_BODY_TAG;
          }

          public void doInitBody() throws JspException {
              pageContext.setAttribute(index, ib);
              i++;
              ib.setValue(i);
          }

          public int doAfterBody() throws JspException {
              try {
                  if (i >= count) {
                      bodyContent.writeOut(bodyContent.getEnclosingWriter());
                      return SKIP_BODY;
                  } else
                      pageContext.setAttribute(index, ib);
                  i++;
                  ib.setValue(i);
                  return EVAL_BODY_TAG;
              } catch (IOException ex) {
                  throw new JspTagException(ex.toString());
              }
          }
      }

#### Sample Tag-Extra-Info Class: ExampleLoopTagTEI.java

Following is the source code for the tag-extra-info class that describes the scripting variable used by the `loop` tag.

A `VariableInfo` instance is constructed that specifies the following for the variable:

- The variable name is according to the `index` attribute.

- The variable is of the type `oracle.jsp.jml.JmlNumber` (this must be specified as a fully qualified class name).

- The variable is newly declared.

- The variable scope is `NESTED`.

In addition, the tag-extra-info class has an `isValid()` method that determines whether the count attribute is valid (it must be an integer).

    package examples;

    import javax.servlet.jsp.tagext.*;

    public class ExampleLoopTagTEI extends TagExtraInfo {
        public VariableInfo[] getVariableInfo(TagData data) {
            return new VariableInfo[]
                {
                    new VariableInfo(data.getAttributeString("index"),
                                     "oracle.jsp.jml.JmlNumber",
                                     true,
                                     VariableInfo.NESTED)
                };
        }

        public boolean isValid(TagData data)
        {
          String countStr=data.getAttributeString("count");
          if (countStr!=null)   // for request time case
          {
            try {
              int count=Integer.parseInt(countStr);
            }
            catch (NumberFormatException e)
            {
              return false;
            }
          }
          return true;
        }
    }

#### Sample Tag Library Description File: exampletag.tld

Following is the tag library description (TLD) file for the tag library. In this example, the library consists of only the one tag, `loop`.

This TLD file specifies the following for the `loop` tag:

- `examples.ExampleLoopTag` is the tag handler class.

- `examples.ExampleLoopTagTEI` is the tag-extra-info class.

- The `bodycontent` specification is `JSP`, meaning the JSP translator should process and translate the body code.

- There are two attributes, `index` and `count`, and both are mandatory. The `count` attribute can be a request-time JSP expression.

      <?xml version="1.0" encoding="ISO-8859-1" ?>
      <!DOCTYPE taglib
              PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
              "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

      <!-- a tab library descriptor -->

      <taglib>
        <!-- after this the default space is
              "http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd"
         -->

        <tlibversion>1.0</tlibversion>
        <jspversion>1.1</jspversion>
        <shortname>simple</shortname>
      <!--
        there should be no <urn></urn> here
      -->
        <info>
              A simple tab library for the examples
        </info>

        <!-- example tag -->
        <!-- for loop -->
        <tag>
          <name>loop</name>
          <tagclass>examples.ExampleLoopTag</tagclass>
          <teiclass>examples.ExampleLoopTagTEI</teiclass>
          <bodycontent>JSP</bodycontent>
          <info>for loop</info>
          <attribute>
              <name>index</name>
              <required>true</required>
          </attribute>
          <attribute>
              <name>count</name>
              <required>true</required>
              <rtexprvalue>true</rtexprvalue>
          </attribute>
        </tag>

      </taglib>

| Copyright © 1996-2000, Oracle Corporation. All Rights Reserved. |
Library | Service | Contents | Index