Announcement Announcement Module
Collapse
No announcement yet.
AbstractXsltView - set XSLT not from disk file? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AbstractXsltView - set XSLT not from disk file?

    Using Spring 2.0

    My XSLT code is in memory as a String (originally from a database) but Spring always seems to expect it from a disk file. I tried over riding getStylesheetLocation() as shown below but this gets called when the app starts up. In fact it gets called twice for some reason, the first seems ok but the second produces -

    org.springframework.context.ApplicationContextExce ption: Can't load XSLT stylesheet from resource loaded from byte array; nested exception is java.io.FileNotFoundException: resource loaded from byte array cannot be resolved to URL
    Caused by:
    java.io.FileNotFoundException: resource loaded from byte array cannot be resolved to URL
    .....................

    public class ReturnXsltView extends AbstractXsltView
    {
    protected Source createXsltSource(Map model, String root,
    HttpServletRequest request, HttpServletResponse response)
    throws Exception {

    String xml = (String) model.get("xml");
    Source streamSource = new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8")));

    return streamSource;
    }

    protected Resource getStylesheetLocation() {
    String xsl = "<?xml version=\"1.0\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"html\" encoding=\"UTF-8\" indent=\"no\"/><xsl:strip-space elements=\"*\"/><xsl:template match=\"/\"><xsl:apply-templates/></xsl:template><xsl:template match=\"TITLES\"><xsl:apply-templates select=\"TITLE\"/></xsl:template><xsl:template match=\"TITLE\"><xsl:apply-templates select=\"DESCRIPTION\"/></xsl:template><xsl:template match=\"DESCRIPTION\"><xsl:element name=\"option\"><xsl:attribute name=\"value\"><xsl:value-of select=\".\"/></xsl:attribute><xsl:value-of select=\".\"/></xsl:element></xsl:template></xsl:stylesheet>";

    Resource res = null;

    try {
    res = new ByteArrayResource(xsl.getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }

    return res;
    }
    }

    Note : Obviously XLST is not hard coded like this but done just to prove a point!

    I assume this is not the correct way to do it then but what is? I want to set the XSLT code to use in the transformation when the view is called for rendering, reason being is the XLST might be different per request!

    I cannot for the life of me see how to do this? is it possible? is so, how/what/where?

    cheers

    harry

  • #2
    The getStyleSheetLocation should only return the location of the StyleSheet, after that the method getStylesheetSource is called and it tries to load the stylesheet.

    You already state that for each request your xslt might differ, so you probably want the getStylesheetLocation to return null (if it returns something that is cached at application startup!).

    You probably want to override/adjust the buildTransformer method, that way you also have access to the model/parameters which might include the information needed to retrieve the xslt from the database.

    Comment


    • #3
      Marten, thanks for such a quick reply (especially on a Sunday!)

      Following your advice I think (gulp!) I might have finally got there! - while looking at buildTransformer() I noticed doTransform() - this gives me the model which has my xslt & xml in so after a bit of fiddling the code below seems to do the trick!

      public class ReturnXsltView extends AbstractXsltView
      {
      protected void doTransform(Map model, Source source,
      HttpServletRequest request, HttpServletResponse response)
      throws Exception {

      Transformer transformer = null;
      TransformerFactory transformerFactory = TransformerFactory.newInstance();

      String xsl = (String) model.get("xsl");

      try
      {
      transformer = transformerFactory.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes("UTF-8"))));

      transformer.transform(source, new StreamResult(response.getOutputStream()));
      } catch (Exception e)
      {
      e.printStackTrace();
      }
      }

      protected Source createXsltSource(Map model, String root,
      HttpServletRequest request, HttpServletResponse response)
      throws Exception {
      Source streamSource = null;
      String xml = (String) model.get("xml");

      streamSource = new StreamSource(new ByteArrayInputStream(xml.getBytes("utf-8")));

      return streamSource;
      }

      protected Resource getStylesheetLocation() {
      return null;
      }
      }

      Hopefully this will help other unfortunate stressed out souls - it actually works!

      cheers

      harry

      Comment

      Working...
      X