Subject: [xsl] URIResolver howto From: "Robert Koberg" <rob@xxxxxxxxxx> Date: Tue, 1 Oct 2002 07:43:44 -0700 |
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Is It Possible to use Jav, Joerg Heinicke | Thread | Re: [xsl] URIResolver howto, Vedu Hariths |
RE: [xsl] replace function, John Pallister | Date | [xsl] multiple if and expression, thomas |
Month |