You're right. The examples of this article can be implemented also with external functions. The reason I didn't take this approach was, originally, that I wanted to keep the XSLT 'clean', and not include any external code in it. Thus the developers of XSLT don't need to know anything about Java. But there's also another, more important, reason. XSLT transformers (at least the ones I've tried) are not very good if the data load is high. If the input data file is tens of megabytes in size, a complicated XSLT transformations just didn't work. (If somebody has a solution to this, I'd very much like to hear about it. Please, send more feedback.) When we pre-process the incoming XML data, we can filter out all the elements which are not needed in the transformation, simplify the input data in some ways etc. For instance, if we are interested only in <PRICE_SUMMARY> part of example2b, the example can easily be changed so that only the PRICE_SUMMARY element is forwarded to the XSLT tranformer. Just associate the FilterCommand with all the irrelevant tags in Example2bCommandFactory:
public Example2bCommandFactory() { FilterCommand myFilterCommand = new FilterCommand(); commands.put("/ORDER_INFO/CUSTOMER", myFilterCommand); commands.put("/ORDER_INFO/CUSTOMER/ID", myFilterCommand); commands.put("/ORDER_INFO/CUSTOMER/SERVICE_ORDERS", myFilterCommand); commands.put("/ORDER_INFO/CUSTOMER/SERVICE_ORDERS/ORDER", myFilterCommand); commands.put("/ORDER_INFO/CUSTOMER/SERVICE_ORDERS/ORDER/TIMESTAMP", myFilterCommand); ProductIdCommand myProductIdCommand = new ProductIdCommand(); commands.put("/ORDER_INFO/CUSTOMER/SERVICE_ORDERS/ORDER/PRODUCT_ID", myProductIdCommand);
PriceCollectorCommand myPriceCollectorCommand = new PriceCollectorCommand(myProductIdCommand); commands.put("/ORDER_INFO/CUSTOMER/SERVICE_ORDERS/ORDER/PRICE", myPriceCollectorCommand); commands.put("/ORDER_INFO", new PriceSummaryPrintingCommand(myPriceCollectorCommand)); }
And modify commands ProductIdCommand and PriceCollectorCommand so that DefaultHandlerInterface is never called (comment out the lines beginning ' _default'):
Even very large input files (I tested one of 40MB) can be processed this way.
I think the simplest solution is usually the best. If you find external XSLT functions simpler, you should use that. That probably works best in many cases. (For readers not familiar with XSLT extensions, this JavaWorld article is a good place to start: http://www.javaworld.com/javaworld/jw-12-2001/jw-1221-xslt.html)
If the amount of input data is huge, and especially if it is received from multiple sources (each with varying format), I'd consider implementing the pre-processor.
Many thanks for your comment.
Samu
|