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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] URIResolver howto, Robert Koberg | Thread | [xsl] multiple if and expression, thomas |
RE: [xsl] replace function, John Pallister | Date | [xsl] modulus operator, Saverio Perugini |
Month |