Re: [xsl] URIResolver howto

Subject: Re: [xsl] URIResolver howto
From: Vedu Hariths <vhariths@xxxxxxxxx>
Date: Tue, 1 Oct 2002 09:55:40 -0700 (PDT)
Thanks for the detailed how-to :)
Vedu
--- Robert Koberg <rob@xxxxxxxxxx> wrote:
> Hi, [I sent this with the wrong email address, sorry
> if it comes through twice]
> 
> I recieved a few requests for a better example of
> how to use the URIResolver. I
> hope the information below helps.
> 
> When you need control over xsl:include/import or the
> document(), you need to use
> an URIResolver - you cannot do it in your
> stylesheet. This is very useful when
> you have a 'primary' XSL[1]  and it includes,
> imports or uses document() to
> bring in other XML/XSL files/streams from two or
> more different points of
> control.
> 
> As a simple example lets say a user logs on to a
> server-side application. The
> user can choose different navigation styles to get
> around a site (dynamic JS or
> static HTML). You would need to somehow get or keep
> a user preference that tells
> the app which nav option they have choosen.
> 
> We might have a primary XSLT like:
> 
> <?xml version="1.0" encoding="ISO-8859-1"?>
> <xsl:stylesheet
>   version="1.0"
>   xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> <xsl:include href="head.xsl"/>
> <xsl:include href="banner.xsl"/>
> <xsl:include href="nav.xsl"/>
> <xsl:include href="footer.xsl"/>
> <xsl:template match="/">
> <html>
>   <xsl:call-template name="head"/>
>   <body>
>     <xsl:call-template name="banner"/>
>     <div id="leftcol">
>       <xsl:call-template name="nav"/>
>     </div>
>     <div id="centercol">
>        call some templates
>     </div>
>     <div id="rightcol">
>       <div class="floater">
>         call some templates
>       </div>
>     </div>
>     <br clear="all"/>
>     <xsl:call-template name="footer"/>
>   </body>
> </html>
> </xsl:template>
> </xsl:stylesheet>
> 
> There are two different sets of the head and nav and
> to keep things modular. So
> you might use static_head.xsl & static_nav.xsl or
> dynamic_head.xsl &
> dynamic_nav.xsl. You need an URIResolver to handle
> which set to include.
> 
> You may have a method that starts transformations in
> the app:
> 
> void xform(ServletContext servlet_context,
> HttpServletRequest req,
> HttpServletResponse res, long _start_time)
>   	throws TransformerException, java.io.IOException
> {
> 
>   System.setProperty(
>     "javax.xml.transform.TransformerFactory",
>     "com.icl.saxon.TransformerFactoryImpl");
>   ServletOutputStream out = res.getOutputStream();
>   HttpSession http_session = req.getSession();
>   String nav_style =
> http_session.getAttribute("nav_style").toString();
>   String source =
> http_session.getAttribute("source").toString();
>   String style =
> http_session.getAttribute("style").toString();
>   try {
>       Templates pss = tryCache(servlet_context,
> style, nav_style);
>       Transformer transformer =
> pss.newTransformer();
>       Properties details =
> pss.getOutputProperties();
>       String mime =
>
pss.getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
>       if (mime==null) {
>         res.setContentType("text/html");
>       } else {
>         res.setContentType(mime);
>       }
>       transformer.setParameter("nav_style",
> nav_style);
>       transformer.transform(
>           new StreamSource(source)),
>           new StreamResult(out));
>       out.close();
>       out.flush();
>     } catch (Exception err) {
>       System.out.println(err);
>     }
> }
> 
> Your tryCache method might look like:
> 
> private synchronized Templates
> tryCache(ServletContext serv_context, String
> path, String nav_style)
>     throws TransformerException, java.io.IOException
> {
>   String full_path = serv_context.getRealPath(path);
>   Templates x = (Templates)this.cache.get(path);
>   if (x==null) {
>       TransformerFactory factory =
> TransformerFactory.newInstance();
>       factory.setURIResolver(new
> MyResolver(serv_context, nav_style));
>       x = factory.newTemplates(new StreamSource(new
> File(full_path)));
>       this.cache.put(path, x);
>   }
>   return x;
> }
> 
> This primary XSLT needs to find files identified in
> the xsl:includes/imports and
> document(). The following URIResolver simply checks
> the href argument
> automatically sent in by the transformation process.
> The href argument is the
> value of the href in the xsl:include/import or the
> first (or only) argument from
> the document function. The base argument is either
> the location of the primary
> XSLT or the second argument in the document(). If it
> sees head.xsl or nav.xsl it
> prepends the filename with the nav style preference
> string:
> 
> class MyResolver implements URIResolver {
>   String base_path;
>   String nav_style;
>   public MyResolver(ServletContext context, String
> style) {
>     this.base_path =
> context.getRealPath("/WEB-INF/styling/");
>     this.nav_style = style;
>   }
> 
>   public Source resolve(String href,String base) {
>     StringBuffer path = new
> StringBuffer(this.base_path);
>     if (href.equals("head.xsl") |
>          href.equals("nav.xsl")) {
>       path.append(this.nav_style);
>       path.append("_");
>     }
>     path.append(href);
>     File file = new File(path.toString());
>     if(file.exists()) return new StreamSource(file);
>     return null;
>   }
> }
> 
> 
> best,
> Rob Koberg
> livestoryboard.com
> 
> [1] the XSL used as the argument in the
> transformation against the main source
> XML
> 
> 
> 
>  XSL-List info and archive: 
> http://www.mulberrytech.com/xsl/xsl-list
> 


__________________________________________________
Do you Yahoo!?
New DSL Internet Access from SBC & Yahoo!
http://sbc.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread