Two Laptop Bag*
The moose likes XML and Related Technologies and the fly likes XSLT transormation issue in loop Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » XML and Related Technologies
Bookmark "XSLT transormation issue in loop" Watch "XSLT transormation issue in loop" New topic
Author

XSLT transormation issue in loop

raj jitu malhotra
Greenhorn

Joined: Feb 05, 2012
Posts: 3
I have the XSLT transformation code as follows which works without any issue for a given set of files

for (File xmlFile : files) {
transformer = tFactory.newTransformer(new StreamSource(strStylesheet));
FileOutputStream os = new FileOutputStream(new File(outputDirs + "/" + xmlFile.getName()));
transformer.transform(new StreamSource(xmlFile), new StreamResult(os));
}


As a part of code re factoring i moved the transformer creation part out of the loop. i.e.

transformer = tFactory.newTransformer(new StreamSource(strStylesheet));
for (File xmlFile : files) {
FileOutputStream os = new FileOutputStream(new File(outputDirs + "/" + xmlFile.getName()));
transformer.transform(new StreamSource(xmlFile), new StreamResult(os));
}


I think the 2nd code snippet is the correct way to invoke the transformer on the set of files. However when i run this code on the same set of files, i get a OutOfMemory Exception.

Can any one let me know why i don't get a memory exception with first snippet when a new transformer is created for every iteration?
Is there something additional i need to take care of while doing the transformation?

StackTrace:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at net.sf.saxon.tinytree.TinyTree.ensureAttributeCapacity(TinyTree.java:250)
at net.sf.saxon.tinytree.TinyTree.addAttribute(TinyTree.java:538)
at net.sf.saxon.tinytree.TinyBuilder.attribute(TinyBuilder.java:263)
at net.sf.saxon.event.ReceivingContentHandler.startElement(ReceivingContentHandler.java:361)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2756)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at net.sf.saxon.event.Sender.sendSAXSource(Sender.java:354)
at net.sf.saxon.event.Sender.send(Sender.java:184)
at net.sf.saxon.event.Sender.send(Sender.java:49)
at net.sf.saxon.Controller.transform(Controller.java:1550)
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
I think the 2nd code snippet is the correct way to invoke the transformer on the set of files. However when i run this code on the same set of files, i get a OutOfMemory Exception.


Why do you think the 2nd code is the the "correct" way? What is the basis for your opinion?

Can any one let me know why i don't get a memory exception with first snippet when a new transformer is created for every iteration?


Why do you think that you should have a memory usage problem? Do you know exactly how TransformerFactory or Transformer work? ... the inner details?
raj jitu malhotra
Greenhorn

Joined: Feb 05, 2012
Posts: 3
Hi Jimmy,

1. as a generic rule i think we have to move any operation which doesn't change inside the loop, outside.

2. as a transformer is created again and again there should be more object creation (memory allocation/de-allocation) in first snippet than the 2nd snippet.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

raj jitu malhotra wrote:2. as a transformer is created again and again there should be more object creation (memory allocation/de-allocation) in first snippet than the 2nd snippet.


Indeed that's correct -- as far as your code is concerned. What is happening is that the Transformer caches various things that it produces. And then when you reuse it, it caches more of those things. Eventually you run out of memory. But reducing the number of objects created is usually a pointless goal. Especially in your case, where you were trying to avoid creating a single object in a loop which would normally create hundreds or thousands of objects. Try to keep things in perspective in the future.

Anyway, last time I went through the tutorials about XSLT in Java, the recommendation was to cache a Templates object rather than a Transformer object. If you really find you have to optimize things, then that would be the way to go. But don't bother until you really find you have to optimize things.
raj jitu malhotra
Greenhorn

Joined: Feb 05, 2012
Posts: 3
thanks paul, that helps...

can you elaborate on your point.....
But reducing the number of objects created is usually a pointless goal.
Jimmy Clark
Ranch Hand

Joined: Apr 16, 2008
Posts: 2187
You attempted to reduce the number of objects created in a for loop and broke the code with a OutOfMemory Exception. In reality, your refactoring ended up creating more objects in the JVM. Sounds pointless to me...
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: XSLT transormation issue in loop
 
Similar Threads
XSLT 2.o : to Use <matches> tag
XML Transformation error
Passing Parameters to XSLT ?
Facing org .apache .xml. dtm. DTMException Not supported
No output from Servlet