Project

Profile

Help

Support #3605

Updated by Michael Kay over 5 years ago

I want to run 2 XSL transformation where the 2nd transformation should be streamable and will work on the output from the 1st transformation. 


 


 The whole scenario is like this:- 

 

 We perform a transformation and get some output. Now from that output we want to filter out all the blank elements(i.e. elements like <child1/>,<child1></child1> and<parent><child1/></parent>) from the xml, so for now we are considering to run the output xml through another XSL transformation which will strip out all the empty elements from the output of first transfromation and give us the final output xml. 


 


 I am able to link 2 transfromations using a TransformerHandler. The approach i followed is simple i set the result of first transformation to TransformerHandler which then performs the second transformation and gives me the desired result. I am facing issues when trying to follow the same approach using a StreamingTransformerHandler, i am having trouble initializing the StreamingTransformerHandler, here's the approach i am following: 


 


 String xsl2="<xsl:stylesheet version=\"3.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +  

                                		  

                                		 "      <xsl:output omit-xml-declaration=\"yes\" indent=\"yes\"/>\n" +  

                                		  

                                		 "      <xsl:mode streamable=\"yes\" on-no-match=\"shallow-copy\"/>\n" +  

                                		  

                                		 "      <xsl:strip-space elements=\"*\"/>\n" +  

                                		  

                                		 "      <xsl:template match=\"*[not(@*)]\">\n" +  

                                		  

                                		 "        <xsl:where-populated>\n" +  

                                		  

                                		 "          <xsl:copy>\n" +  

                                		  

                                		 "              <xsl:apply-templates select=\"@*\"/>\n" +  

                                		  

                                		 "              <xsl:apply-templates select=\"node()\"/>\n" +  

                                		  

                                		 "          </xsl:copy>\n" +  

                                		  

                                		 "        </xsl:where-populated>    \n" +  

                                		  

                                		 "      </xsl:template>\n" +  

                                		  

                                		 "      <xsl:template match=\"text()[number(.) = -1]\"/>\n" +  

                                		  

                                		 "</xsl:stylesheet>"; 

                                 

                                 BufferedInputStream xsl2Stream = new BufferedInputStream(new ByteArrayInputStream(xsl2.getBytes())); 

                                 

                                 StreamSource src2 = new StreamSource(xsl2Stream); 

                                 

                                 Templates removeEmptyXSLTemplates= _transformerFactory.newTemplates(src2); 

                                 

                                 StreamingTransformerFactory stf = new StreamingTransformerFactory(); 

 

 //                                  SAXTransformerFactory stf2 = (SAXTransformerFactory)TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl", null); 

                                 

                                 StreamingTransformerHandler sth = (StreamingTransformerHandler) stf.newTransformerHandler(removeEmptyXSLTemplates); 

                                 

                                 sth.setResult(_result); 

                                 

                                 _transformer.transform(new StreamSource(getSourceStream()), new SAXResult(sth)); 


 


 If i change the sth from StreamingTransformerHandler to TransformerHandler the code works fine. The newTransformerHandler returns a TransformerHandler i assumed that we should be able to cast it into a StreamingTransformerHandler and hence tried this approach but that's not the case and hence i got the following exception: 

 

 net.sf.saxon.jaxp.TransformerImpl cannot be cast to net.sf.saxon.jaxp.StreamingTransformerImpl  

  

 So i am not able to execute my 2nd transformation with streaming. 

 

 If there's anyway to make 2nd transformation streamable without converting the output of first transformation to input source OR if there's a way with which i can achieve my desired results without having a 2nd transformation that will be the best case for that i am attaching a sample input and my desired output. 
 

Back