xsl-list
[Top] [All Lists]

[xsl] RE: Issue with document('') under Xalan-Java

2010-01-20 08:37:39
Nicholas W 4407(_at_)log1(_dot_)net wrote:

I am creating an XSL transformer like this:

TransformerFactory transformerFactory = TransformerFactor.newInstance();
transformerFactory.setAttribute("indent-number", new Integer(2));
Transformer trans = transformerFactory.newTransformer(sheetSource);

And in my document I have something like this:

<xsl:variable name="langs-top" select="document('')/*/l:languagecodes"/>

However I cannot seem to get this to work, it seems that the langs-top
variable is always empty. Even if I do something like this:

<xsl:variable name="langs-top" select="document('')"/>

it seems to be empty. Is it possible to use document('') in
Xalan-Java, or is there something I am not doing correctly?

You're not alone in facing this problem, Nicholas.  Andrew Welch and Michael
Kay are right that you need to set the systemId on the stream source.
Unfortunately, I've not seen a complete solution or example anywhere in the
list archives or on the Internet that deals with all of the pitfalls (such
as stylesheets included by other stylesheets and the quirky behavior of
URIResolvers in different servlet engines).

Assuming you're doing the transformations within a servlet, to set things
up, you'll need something like:

    // Get the resource as an InputStream from the servlet
    // context, wrap it in a StreamSource, and set its
    // systemId to its real path on the file system.
    InputStream inputStream = context.getResourceAsStream(path);
    Source streamSource = new StreamSource(inputStream);
    String realPath = context.getRealPath(path);

    // Some servlet engines use '\' instead of '/' in
    // the paths they return.  Our systemId path must
    // not contain backslashes.
    String cleansedRealPath = realPath.replace('\\', '/');
    streamSource.setSystemId(cleansedRealPath);

    TransformerFactory factory = TransformerFactory.newInstance();
    factory.setURIResolver(uriResolver);

    URIResolver uriResolver = new ServletContextURIResolver(context);
    Transformer transformer = factory.newTransformer(streamSource);
    transformer.setURIResolver(uriResolver);

The code above sets the systemId on the original stylesheet source.
However, it does not set the systemId for any stylesheets included by the
original stylesheet.  To do so, note that you'll need a URIResolver: 

public class ServletContextURIResolver implements URIResolver, Serializable
  {

  public ServletContextURIResolver(
    ServletContext servletContext)
    {
    setServletContext(servletContext);
    }

  public Source resolve(
    String href,
    String basePath)
    {
    Source source = null;
    
    System.out.println("href: " + href);
    System.out.println("basePath: " + basePath);
    
    // Sometimes the incoming href will be null or the
    // empty string, depending on the servlet engine.
    // Return null in either of those cases.
    if (href != null)
      {
      boolean isEmptyHRef = href.equals("");
      if (!isEmptyHRef)
        {
        // Get the resource as an InputStream from the servlet
        // context, wrap it in a StreamSource, and set its
        // systemId to its real path on the file system.
        ServletContext context = getServletContext();
        InputStream inputStream = context.getResourceAsStream(href);
        if (inputStream != null)
          {
          source = new StreamSource(inputStream);
          
          String realPath = context.getRealPath(href);
          System.out.println("realPath: " + realPath);

          // Some servlet engines use '\' instead of '/' in
          // the paths they return.  Our systemId path must
          // not contain backslashes.
          String cleansedRealPath = realPath.replace('\\', '/');
          System.out.println("cleansedRealPath: " + cleansedRealPath);
          source.setSystemId(cleansedRealPath);
          }
        }
      }
    
    System.out.println("source: " + source);

    return source;
    }
  . . . 
  }

Roger

--
Roger L. Cauvin
@rcauvin (Twitter)
cauvin.blogspot.com (blog)




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>
  • [xsl] RE: Issue with document('') under Xalan-Java, Roger L. Cauvin <=