You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by "Roytman, Alex" <ro...@peacetech.com> on 2001/03/06 05:56:32 UTC

Xalan2 several problems building Templates from SAX. Demo project attached

I encountered several problems with Xalan 2. I apologies in advance if these
problems came from my lack of experience with Xalan 2. I just started
transitioning my web framework to Xalan2.

The problems manifest themselves in case I build stylesheet from SAXSource
which has chain of filters as an XMLReader
Here I only list these problems please see my comments in the java source 

- Logical problem with SAXSource.setSystemId()
- TemplatesHandler outputs DTD 
- TemplatesHandler reports SystemId Unknown and crashes

This is the source code for your convenience. Entire project including
xsl/xml files is attached:



package xalantest;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.XMLReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;

import javax.xml.transform.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;

/*
This sample suppose to generate a stylesheet by another stylesheet to an xml
file
It does not work hovewer
There are of course other ways to achieve the same functionality but I
wanted to return
a Source rather than Templates object so it can be used with all TraX API
*/

public class Xalan2test {
  private final SAXTransformerFactory transformerFactory =
(SAXTransformerFactory)SAXTransformerFactory.newInstance();
  private final SAXParserFactory parserFactory =
SAXParserFactory.newInstance();

  public Xalan2test() {
    parserFactory.setNamespaceAware(true);
  }

  public Source getTemplatesSource(String styleId, String xmlId) throws
Exception {
    XMLReader reader = parserFactory.newSAXParser().getXMLReader();
    reader.setFeature("http://apache.org/xml/features/validation/dynamic",
true);
    Templates style = transformerFactory.newTemplates(new
StreamSource(styleId));
    XMLFilter styleReader = transformerFactory.newXMLFilter(style);
    //in this simple case we could skip setting parent because it is just a
parser
    //but in other cases parent is some special filter or chain of filters
    styleReader.setParent(reader);
    InputSource xmlInputSource = new InputSource(xmlId);
    Source styleSource = new SAXSource(styleReader, xmlInputSource);
    //There is a logical problem in SAXSource I believe
    //I would expect that calling styleSource.setSystemId(styleId) on
SAXSource will set systemId
    //(we need systemId so TemplatesHandler would have proper context to
resolve all external references)
    //for the stylesheet instead it calls setSystemId(styleId) on
xmlInputSource and overrides its systemId
    //When we use chain of XMLFilters xmlInputSource gets passed through the
chain of XMLFilters and
    //gets processed by the very first one and systemId we supplied for
xmlInputSource is used by that filter
    //The TemplatesHandler (which is the last in the chain( have to deal
with source which has no systemId
    //and will not be able to resolve external references
    return styleSource;
  }

  //there is a strange problem here
  //it outputs DTD as a part of stylesheet
  public void print(Source src) throws Exception {
    Transformer trans = transformerFactory.newTransformer();
    trans.setOutputProperty("indent", "yes");
    trans.transform(src, new StreamResult(System.out));
  }

  //it does not work
  //blows with message: SystemId Unknown; Line 0; Column 0; SystemId
Unknown; Line 0; Column 0; SystemId Unknown;
  //and then prints bits of stack trace in edless loop
  public void transform(Source styleSrc, String xmlId) throws Exception {
    Templates style = transformerFactory.newTemplates(styleSrc);
    style.newTransformer().transform(new StreamSource(xmlId), new
StreamResult(System.out));
  }

  public static void main(String[] args) {
    //please set it to point to your directory
    String base = "file:/work/jbproject/xalantest/";
    Xalan2test xt = new Xalan2test();
    try {
      Source src = xt.getTemplatesSource(base + "style/hello.xsl", base +
"meta/alex.xml");
      xt.print(src);
      xt.transform(src, base + "data/data.xml");
    } catch (Exception ex) {
      ex.printStackTrace();
    }

  }
}