This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: URIResolver howto
- From: Vedu Hariths <vhariths at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Tue, 1 Oct 2002 09:55:40 -0700 (PDT)
- Subject: Re: [xsl] URIResolver howto
- Reply-to: xsl-list at lists dot mulberrytech dot com
Thanks for the detailed how-to :)
Vedu
--- Robert Koberg <rob@koberg.com> 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