RE: [xsl] Re: using SAX events in URIResolver (Xalan and Saxon)

Subject: RE: [xsl] Re: using SAX events in URIResolver (Xalan and Saxon)
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sun, 16 Jan 2005 18:27:46 -0000
I'm very confused by what you're trying to do here.

You've got a transformation T, running in the form of a TransformerHandler,
that calls the document function to access a document D. You say "The
Transformer resolver sends the current TransformerHandler to a method that
uses it to send SAX events." So D is actually the output of T - or have I
misunderstood? This sounds to me as if you are trying to get the
transformation to read its own output. Surely it shouldn't be surprising if
this causes some kind of infinite loop?

Michael Kay
http://www.saxonica.com/



> -----Original Message-----
> From: Robert Koberg [mailto:rob@xxxxxxxxxx] 
> Sent: 16 January 2005 16:13
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Re: using SAX events in URIResolver (Xalan and Saxon)
> 
> Hi,
> 
> I have gotten a little further along, but still cannot make 
> this work. I 
> have tried this with 4 XSL processors: Saxon 6.5.3, Xalan (both 
> interpretive and XSLTC - latest release) and Resin 2.1.14.
> 
> I am using two URIResolvers - one for the 
> SAXTransformerFactory and then 
> another one for the Transformer. This simply will not work with the 
> compiling processors (XSLTC and Resin) because they ONLY allow you to 
> set the URIResolver on the TransformerFactory and ignore the 
> resolver on 
> the Transformer. Just to be clear, the Templates (TransformerFactory) 
> resolver only has to worry about resolving XSL files and the 
> Transformer 
> resolver only has to worry about resolving XML files they are 
> authorized 
> to use (or return a well-formed error to the transform if 
> source/file is 
>   not found or is not allowed). The Transformer resolver sends the 
> current TransformerHandler to a method that uses it to send 
> SAX events.
> 
> For Saxon and Xalan(interpretive), the error seems similar. Note: the 
> transformation works when not using SAX events. Using SAX 
> events, I seem 
> to have created an endless loop. Saxon loops until I stop the app.
> Xalan stops after the first iteration with the error:
> 
> (Location of error unknown)Can not load requested doc: Variable 
> focus_dc_identifier is directly or indirectly
> referencing itself!
> Warning: popContextNodeList when stack is empty!
> 
> Here is the variable definition:
> 
> <xsl:variable
>    name="focus_metadata_path"
>    select="concat('metadata/', $lsb_focus_localName, '/', 
> $user.focus.idref, '.xml')"/>
> 
> <xsl:variable name="lsb_focus_metadata" 
> select="document($focus_metadata_path)/*"/>
> 
> <xsl:variable name="focus_dc_identifier">
>    <xsl:variable name="dcElem" 
> select="$lsb_focus_metadata/s:dc/dc:identifier"/>
>    <xsl:choose>
>      <xsl:when test="not($dcElem)">
>        <xsl:text>http://</xsl:text>
>        <xsl:value-of select="$project.domain"/>
>        <xsl:apply-templates select="$lsb_focus_nodeset" 
> mode="getNamePath"/>
>      </xsl:when>
>      <xsl:otherwise>
>        <xsl:value-of select="normalize-space($dcElem)"/>
>      </xsl:otherwise>
>    </xsl:choose>
> </xsl:variable>
> 
> 
> and it is only referenced here (in this scenario):
> 
> <meta content="{$focus_dc_identifier}" name="DC.identifier"/>
> 
> 
> The java code looks like:
> 
> //uses a cached Templates object to create the TransformerHandler.
> // the Templates object uses its own URIResolver to resolve 
> xsl:imports
> TransformerHandler transformerHandler = project.getTransformerHandler(
>        lsb, xslFile, refreshXslCache);
> 
> ServletOutputStream out = response.getOutputStream();
> 
> try {
> // tried two ways to set the Result
> 
>    //SerializerFactory serializerFactory = 
> SerializerFactory.getSerializerFactory("xml");
>    //Serializer serializer = serializerFactory.makeSerializer(new 
> OutputFormat());
>    //serializer.setOutputByteStream(out);
> 
>    Result result = new SAXResult(transformerHandler);
>    //Result result = new SAXResult(serializer.asContentHandler());
> 
>    transformerHandler.setResult(result);
> 
>    Transformer transformer = transformerHandler.getTransformer();
> 
> // a different URIResolver for XML requested by the document function
> // it passes the current TransformerHandler to be used to 
> output SAX events
>    transformer.setURIResolver(user.getTransformerUriResolver(
>                transformerHandler, lsb, project));
> 
>    Properties params = getParamProperties(project, user, request,
>            focusElem);
> 
>    Enumeration e = params.propertyNames();
> 
>    while (e.hasMoreElements()) {
>        String name = (String) e.nextElement();
>        transformer.setParameter(name, params.getProperty(name));
>    }
> 
> // treeMgr.getSource() is a org.dom4j.io.DocumentSource
> // which extends SAXSource. It is basically a configuration tree
> // that tells the transformation which files to gather with the
> // document function.
>    transformer.transform(treeMgr.getSource(), result);
> 
>    ....
> 
> 
> 
> 
> Xalan's stacktrace is:
> 
> javax.xml.transform.TransformerException: 
> java.lang.ArrayIndexOutOfBoundsException:
> -2
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transformNode(Tra
> nsformerImpl.java:1339)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:673)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:1192)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:1170)
> 	at com.livestoryboard.actions.Preview.service(Unknown Source)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
> 	at 
> com.caucho.server.http.FilterChainServlet.doFilter(FilterChain
> Servlet.java:96)
> 	at 
> com.livestoryboard.actions.EntryFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.livestoryboard.actions.PermissionsFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.livestoryboard.actions.CheckUserFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.caucho.server.http.Invocation.service(Invocation.java:315)
> 	at 
> com.caucho.server.http.CacheInvocation.service(CacheInvocation
> .java:135)
> 	at 
> com.caucho.server.http.RunnerRequest.handleRequest(RunnerReque
> st.java:346)
> 	at 
> com.caucho.server.http.RunnerRequest.handleConnection(RunnerRe
> quest.java:274)
> 	at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
> 	at java.lang.Thread.run(Thread.java:534)
> Caused by: java.lang.ArrayIndexOutOfBoundsException: -2
> 	at org.apache.xpath.VariableStack.unlink(VariableStack.java:212)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.applyTemplateToNo
> de(TransformerImpl.java:2215)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transformNode(Tra
> nsformerImpl.java:1276)
> 	... 18 more
> ---------
> java.lang.ArrayIndexOutOfBoundsException: -2
> 	at org.apache.xpath.VariableStack.unlink(VariableStack.java:212)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.applyTemplateToNo
> de(TransformerImpl.java:2215)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transformNode(Tra
> nsformerImpl.java:1276)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:673)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:1192)
> 	at 
> org.apache.xalan.transformer.TransformerImpl.transform(Transfo
> rmerImpl.java:1170)
> 	at com.livestoryboard.actions.Preview.service(Unknown Source)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
> 	at 
> com.caucho.server.http.FilterChainServlet.doFilter(FilterChain
> Servlet.java:96)
> 	at 
> com.livestoryboard.actions.EntryFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.livestoryboard.actions.PermissionsFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.livestoryboard.actions.CheckUserFilter.doFilter(Unknown Source)
> 	at 
> com.caucho.server.http.FilterChainFilter.doFilter(FilterChainF
> ilter.java:88)
> 	at 
> com.caucho.server.http.Invocation.service(Invocation.java:315)
> 	at 
> com.caucho.server.http.CacheInvocation.service(CacheInvocation
> .java:135)
> 	at 
> com.caucho.server.http.RunnerRequest.handleRequest(RunnerReque
> st.java:346)
> 	at 
> com.caucho.server.http.RunnerRequest.handleConnection(RunnerRe
> quest.java:274)
> 	at com.caucho.server.TcpConnection.run(TcpConnection.java:139)
> 	at java.lang.Thread.run(Thread.java:534)

Current Thread