Todd, I'm reading this too fast... it's been a crazy week.  So forgive any
incorrect info.   (Actually every week is crazy these days).

>    243     XMLReader xslReader = getJAXPXMLReader();
>   244     xslReader.setContentHandler(templatesHandler);
>   245
>   246     // Timed: read/build Templates from StreamSource
>   247     startTime = System.currentTimeMillis();
>   248     xslReader.parse(QetestUtils.filenameToURL(xslName));

Unless I'm misreading, this should be enough  to tell Xalan what the base
URL (system ID) is.  This is because the reader will call
ContentHandler#setDocumentLocator(Locator locator), which is enough to tell
org.apache.xalan.processor.StylesheetHandler where system ID location is
(and other things, like line numbers... very useful!!!).  Note that the
Locator object is set once, and then is kept updated according to the
current line by the parser.

If your ContentHandler event provider doesn't call setDocumentLocator, only
then do you have to call
templatesHandler.setSystemId(QetestUtils.filenameToURL(xslName));.  As a
matter of fact, setSystemId isn't really needed for the API given
setDocumentLocator... I guess it was just put there as a bit more
convenient than setDocumentLocator (it's been long enough that I don't
remember...).

Anyhow, hope this makes sense and is useful.  (Or I may be in too great of
a rush and it might be garbage).

-scott




                                                                                       
                                                
                      "G. Todd Miller -                                                
                                                
                      XML Tech Ctr -           To:       [EMAIL PROTECTED]      
                                                
                      Development"             cc:       [EMAIL PROTECTED], 
(bcc: Scott Boag/Cambridge/IBM)                      
                      <Glenn.Miller@Sun        Subject:  setSystemId() and 
TemplatesHandlers - Xalan Conf Tests (trax.sax)             
                      .COM>                                                            
                                                
                                                                                       
                                                
                      05/09/2002 02:11                                                 
                                                
                      PM                                                               
                                                
                      Please respond to                                                
                                                
                      xalan-dev                                                        
                                                
                                                                                       
                                                
                                                                                       
                                                





If anyone is Xalan-land can help with this it would be great. The XSLTC
trax implementation is having difficulty passing a bunch of xalan conf
tests
when the flavor is trax.sax (uses SAXSources rather than streams). The
problem arises when there is an included stylesheet such as :

  <xsl:include href="periodgroup.xsl"/>

We throw a java.io.FileNotFoundException because at that point in the
compilation of an xsl stylesheet (read in as a SAXSource) we don't know
the system Id of the stylesheet and the only thing we can do is to look
for the included stylesheet (relative path) in the current directory.


java.io.FileNotFoundException: Could not load file periodgroup.xsl
at org.apache.xalan.xsltc.compiler.Include.parseContents(Include.java:127)
at
org.apache.xalan.xsltc.compiler.Stylesheet.parseOwnChildren(Stylesheet.java:

   404)
at
org.apache.xalan.xsltc.compiler.Stylesheet.parseContents(Stylesheet.java:
   376)
at org.apache.xalan.xsltc.compiler.Parser.createAST(Parser.java:380)
at org.apache.xalan.xsltc.trax.TemplatesHandlerImpl.getTemplates(
   TemplatesHandlerImpl.java:152)
at
org.apache.qetest.xslwrapper.TraxSAXWrapper.transform(TraxSAXWrapper.java:
   252)
...


The Xalan conf test harness code that is mentioned at the bottom of the
stack
trace looks like this:


   229 public long[] transform(String xmlName,String xslName, String
resultName)
   230          throws Exception
   231  {
   232     preventFootShooting();
   233     long startTime = 0;
   234     long xslBuild = 0;
   235     long transform = 0;
   236     long resultWrite = 0;
   237
   238     // Create a ContentHandler to handle parsing of the xsl
   239     TemplatesHandler templatesHandler =
saxFactory.newTemplatesHandler();
   240
   241     // Create an XMLReader and set its ContentHandler.
   242     // Be sure to use the JAXP methods only!
   243     XMLReader xslReader = getJAXPXMLReader();
   244     xslReader.setContentHandler(templatesHandler);
   245
   246     // Timed: read/build Templates from StreamSource
   247     startTime = System.currentTimeMillis();
   248     xslReader.parse(QetestUtils.filenameToURL(xslName));
   249     xslBuild = System.currentTimeMillis() - startTime;
   250
   251     // Get the Templates object from the ContentHandler.
 >>252     Templates templates = templatesHandler.getTemplates();
   253

In the test code, a TemplatesHandler (line 239) is used as a ContentHandler
for an XMLReader. As such, the XMLReader (xslReader,244) will parse a
stylesheet (line 248) into SAX Events. The TemplatesHandler from line 239
will receive those SAX Events and process them into a Templates (translet)
object that will be used to transform an input XML document further down
stream.  The test code gets the newly created Templates object on line
252. This Templates object has been created from the parsed stylesheet.

On line 252, a call to getTemplates() is made before any system Id is
set. According to the javadoc for the interface 'TemplatesHandler'
(javax.xml.transform.sax package), the 'setSystemId(String)' method
must be called on the TemplatesHandler *before* the startDocument event
is received by the TemplatesHandler. This is clearly not the case in
the test code.

In fact, if I introduce a new line (>>>) that set the system id as in this
code:

   238   // Create a ContentHandler to handle parsing of the xsl
   239   TemplatesHandler templatesHandler = saxFactory.newTemplatesHandler
();
 >>>     templatesHandler.setSystemId(QetestUtils.filenameToURL(xslName));
   240
   241   // Create an XMLReader and set its ContentHandler.

then XSLTC passes the tests (actually there are 59 more passes!)

Somehow Xalan does pass the test even without the setSystemId line proposed
above. I do not know how this is accomplished at this point.

I do not see how we can figure out the systemId ourselves in this test code
example. Again, looking at the test code above, the first time the
systemId is made known to the program is on line 248, when the XMLReader
is asked to parse the stylesheet. This information is known to the
XMLReader,
however the XMLReader is not our code, and it does not forward this
information
to the contained ContentHandler, which in this case is our XSLTC
TemplatesHandler. The TemplatesHandler only job is to sit there and absorb
SAX events. But there is no information in the SAX events on 'where' they
came from (i.e. the systemId of the Source). One scenario would be for
the TemplatesHandler, upon receipt of the 'startDocument' SAX event,
to ask the XMLReader for information about the Source it has parsed.
However, the TemplatesHandler is contained by the XMLReader and has no
outward reference to its container. Only the XMLReader has a reference
into the contained TemplatesHandler- not the other way around.

Any ideas?  Should Xalan conf test insert the 'setSystemId' call as
proposed?
Why can Xalan handle this without the setSystemId call?

-Todd


=======================================================================
G. Todd Miller                        Sun Microsystems Computer Company
Software Systems Engineer             2 Network Drive, MS UBUR02-201
GE&IS XML Tech Center                 Burlington, MA 01803-0903
                                      781 442-0176
                                      781 442-1437 (fax)
                                      [EMAIL PROTECTED]






Reply via email to