<title>XSL Tag</title>

<p/>An XSL tag can take advantage of Resin's XSL API to transform the body
of a tag using a stylesheet.  Although it's significantly less efficient
than <var/XTP/>, this kind of tag still has useful applications.

<subsection title="Using the XSL tag">

<p/>The XSL tag applies the stylesheet to the tag contents.  The stylesheet
will convert meaningful content tags into HTML formatting.

<p/>Because the content and the style are separated, it will now be easy
to change the stylesheet for a different format.

<example title="xsl.jsp">
<example>
&lt;%@ taglib prefix="ct" uri="/WEB-INF/taglib.tld" %>
&lt;%
 String author = "John Doe";
 String title = "A Guide to XSL";
%>

&lt;ct:xsl stylesheet="tag.xsl">
&lt;item>
  &lt;author>&lt;%= author %>&lt;/author>
  &lt;title>&lt;%= title %>&lt;/title>
&lt;/item>
&lt;/ct:xsl>
</example>
<results>
Author: &lt;b>John Doe&lt;/b>&lt;br>
Title: &lt;em>A Guide to XSL&lt;/em>&lt;br>
</results>
</example>

<p/>The following stylesheet uses <var/StyleScript/>, Resin's readable
syntax for XSL.  You can, of course, convert this example to use strict
XSL.

<p/>This example needs to explicitly set the <var/output method/> to HTML so
the <var/&lt;br>/> tag will be printed properly.  Using normal XML rules,
that tag would be printed as <var/&lt;br/>/>.

<example title="tag.xsl">
$output(method=>html);

item &lt;&lt;
  Author: $apply-templates(author);&lt;br/>
  Title: $apply-templates(title);&lt;br/>
>>

author &lt;&lt;
&lt;b>$apply-templates();&lt;/b>
>>

title &lt;&lt;
&lt;em>$apply-templates();&lt;/em>
>>
</example>

</subsection>

<subsection title="Implementation of the XSL Tag">

The implementation transforms a string to another string.  The XSL API
itself can transform many input formats to many output formats, but well
just use the easiest one.

<p/>The stylesheet is compiled to a Java class for performance, and the
<var/StylesheetFactory/> is intelligent enough to load an already-compiled
class to avoid overhead.

<ol>
<li>Set the stylesheet search path.
<li>Create the StyleScript factory.
<li>Parse the stylesheet.
<li>Create a transformer.
<li>Transform the string.
</ol>

<p/>One twist that's thrown into this example is the use of <var/MergePath/>.
MergePath lets you combine several directories into a single search path and
treat the whole combination as a single Path object.  We'll use that do
duplicate the search path used by the XTP and XSL-Filter servlets.

<example title="XslTag.java">
package test;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

import com.caucho.transform.*;
import com.caucho.vfs.*;
import com.caucho.xsl.*;

public class XslTag extends BodyTagSupport {
  private String stylesheet = "default.xsl";

  public void setStylesheet(String stylesheet)
  {
    this.stylesheet = stylesheet;
  }
  
  public int doEndTag()
    throws JspException
  {
    HttpServletRequest req;
    req = (HttpServletRequest) pageContext.getRequest();
    
    Path pwd = Vfs.lookup(req.getRealPath("/"));
    
    ServletContext app = pageContext.getServletContext();

    Path appDir = Vfs.lookup(app.getRealPath("/WEB-INF/xsl"));

    // search pwd, then appDir, then the classpath/>
    MergePath mergePath = new MergePath();
    mergePath.addMergePath(pwd);
    mergePath.addMergePath(appDir);
    mergePath.addClassPath(getClass().getClassLoader());
      
    try {
      // use StyleScript
      StylesheetFactory factory = new StyleScript();

      // set the search path
      factory.setStylePath(mergePath);

      // create the stylesheet
      Stylesheet xsl = factory.newStylesheet(stylesheet);

      StringTransformer transformer = xsl.newStringTransformer();

      String body = getBodyContent().getString();

      // transform the body
      String value = transformer.transformString(body);

      JspWriter out = pageContext.getOut();

      out.print(value);
    } catch (Exception e) {
      throw new JspException(e.toString());
    }

    return SKIP_PAGE;
  }
}
</example>

</subsection>

<section title="Summary">
<ul>
<li>Althought <var/XTP/> is more efficient, you can use inline
XSL tranformations.
<li><var/StyleScript/> is a readable syntax for XSL.
<li><var/MergePath/> creates search paths with the Path API.
<li><var/StringTransformer/> transforms strings to strings.
</ul>
</section>