DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG· RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=33868>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND· INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=33868 Summary: [PATCH] Xslt task should support "<?xml-stylesheet ... ?>" Product: Ant Version: unspecified Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Core tasks AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] Problem: The Xslt core task has a required "style" attribute which specifies a single stylesheet to be used for transforming, even if multiple xml source files are processed in one task run. IMHO this is a major flexibility drawback and not a good thing :) Solution: The TraX API knows about the "xml-stylesheet" processing instruction. This instruction in an xml source file tells the XSLT processor which stylesheet to use for transforming this particular xml file. The Xslt task should support this, so if no style attribute is given, it would try to use the stylesheet(s) specified by processing instruction in the xml source file(s). Implementation: The following patch implements the solution mentioned above. It was generated against todays HEAD revision and affects three files: /ant/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java /ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java /ant/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java Limitations: - The W3C recommendation defining the "xml-stylesheet" processing instruction allows any number of them to show up in an xml file. The active one is selected by several optional pseudo-attributes of the processing instructions on each trasformation run. The patch doesnt support this, but it wouldnt be hard to do. - Works for TraX processors only. Forget about the others anyway... :) - The reloadstylesheet attribute of the Xslt task is implicitly set true if the xml-stylesheet proc. inst. are used. ---------------------------------- snip ------------------------------------- Index: src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java =================================================================== RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java,v retrieving revision 1.7 diff -u -r1.7 XSLTLiaison2.java --- src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java 9 Mar 2004 16:48:07 -0000 1.7 +++ src/main/org/apache/tools/ant/taskdefs/XSLTLiaison2.java 6 Mar 2005 08:39:25 -0000 @@ -17,6 +17,9 @@ package org.apache.tools.ant.taskdefs; +import java.io.File; +import org.apache.tools.ant.BuildException; + /** * Extended Proxy interface for XSLT processors. * @@ -28,4 +31,9 @@ * Configure the liasion from the XSLTProcess task */ void configure(XSLTProcess xsltTask); + + /** + * Get the stylesheet for an xml source file + */ + File getStylesheet(File xmlFile) throws BuildException; } Index: src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java =================================================================== RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java,v retrieving revision 1.90 diff -u -r1.90 XSLTProcess.java --- src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java 6 Jan 2005 12:05:05 -0000 1.90 +++ src/main/org/apache/tools/ant/taskdefs/XSLTProcess.java 6 Mar 2005 08:39:28 -0000 @@ -36,7 +36,7 @@ * Processes a set of XML documents via XSLT. This is * useful for building views of XML based documentation. * - * @version $Revision: 1.90 $ + * @version $Revision: 1.78.2.7 $ * * @since Ant 1.1 * @@ -197,10 +197,6 @@ String[] list; String[] dirs; - if (xslFile == null) { - throw new BuildException("no stylesheet specified", getLocation()); - } - if (inFile != null && !inFile.exists()) { throw new BuildException("input file " + inFile.toString() + " does not exist", getLocation()); } @@ -219,17 +215,35 @@ log("Using " + liaison.getClass().toString(), Project.MSG_VERBOSE); - File stylesheet = getProject().resolveFile(xslFile); - if (!stylesheet.exists()) { - stylesheet = FILE_UTILS.resolveFile(baseDir, xslFile); - /* - * shouldn't throw out deprecation warnings before we know, - * the wrong version has been used. - */ - if (stylesheet.exists()) { - log("DEPRECATED - the style attribute should be relative " - + "to the project\'s"); - log(" basedir, not the tasks\'s basedir."); + /* if no style attribute is given, the stylesheet will be + * determined by the "xml-stylesheet" processing directive + * of every single xml file + */ + File stylesheet = null; + if (xslFile == null) { + if (!(liaison instanceof XSLTLiaison2)) { + throw new BuildException( + "attribute \"style\" is required if \"processor\" is not \"trax\"", + getLocation()); + } + log("Using \"xml-stylesheet\" processing directive(s), " + + " the reloadstylesheet attribute is set to \"true\"", + + Project.MSG_INFO); + this.reuseLoadedStylesheet = false; + } + else { + stylesheet = getProject().resolveFile(xslFile); + if (!stylesheet.exists()) { + stylesheet = FILE_UTILS.resolveFile(baseDir, xslFile); + /* + * shouldn't throw out deprecation warnings before we know, + * the wrong version has been used. + */ + if (stylesheet.exists()) { + log("DEPRECATED - the style attribute should be relative " + + "to the project\'s"); + log(" basedir, not the tasks\'s basedir."); + } } } @@ -464,7 +478,6 @@ File inF = null; try { - long styleSheetLastModified = stylesheet.lastModified(); inF = new File(baseDir, xmlFile); if (inF.isDirectory()) { @@ -493,15 +506,7 @@ outF = new File(destDir, outFileName[0]); - if (force - || inF.lastModified() > outF.lastModified() - || styleSheetLastModified > outF.lastModified()) { - ensureDirectoryFor(outF); - log("Processing " + inF + " to " + outF); - - configureLiaison(stylesheet); - liaison.transform(inF, outF); - } + update(inF, outF, stylesheet); } catch (Exception ex) { // If failed to process document, must delete target document, // or it will not attempt to process it the second time @@ -526,25 +531,11 @@ private void process(File inFile, File outFile, File stylesheet) throws BuildException { try { - long styleSheetLastModified = stylesheet.lastModified(); log("In file " + inFile + " time: " + inFile.lastModified(), Project.MSG_DEBUG); log("Out file " + outFile + " time: " + outFile.lastModified(), Project.MSG_DEBUG); - log("Style file " + xslFile + " time: " + styleSheetLastModified, - Project.MSG_DEBUG); - if (force || inFile.lastModified() >= outFile.lastModified() - || styleSheetLastModified >= outFile.lastModified()) { - ensureDirectoryFor(outFile); - log("Processing " + inFile + " to " + outFile, - Project.MSG_INFO); - configureLiaison(stylesheet); - liaison.transform(inFile, outFile); - } else { - log("Skipping input file " + inFile - + " because it is older than output file " + outFile - + " and so is the stylesheet " + stylesheet, Project.MSG_DEBUG); - } + update(inFile, outFile, stylesheet); } catch (Exception ex) { log("Failed to process " + inFile, Project.MSG_INFO); if (outFile != null) { @@ -555,6 +546,38 @@ } /** + * Configure and call the liaison transformation + * + * @param inFile the input file to process. + * @param outFile the destination file. + * @param stylesheet the stylesheet to use. + */ + private void update(File inFile, File outFile, File stylesheet) + throws BuildException, Exception { + File xslFile; + if (stylesheet == null) { + xslFile = ((XSLTLiaison2)liaison).getStylesheet(inFile); + } + else { + xslFile = stylesheet; + } + log("Style file " + xslFile + " time: " + xslFile.lastModified(), + Project.MSG_DEBUG); + if (force || inFile.lastModified() >= outFile.lastModified() + || xslFile.lastModified() >= outFile.lastModified()) { + ensureDirectoryFor(outFile); + log("Processing " + inFile + " to " + outFile, Project.MSG_INFO); + configureLiaison(xslFile); + liaison.transform(inFile, outFile); + } else { + log("Skipping input file " + inFile + + " because it is older than output file " + outFile + + " and so is the stylesheet " + stylesheet, + Project.MSG_DEBUG); + } + } + + /** * Ensure the directory exists for a given file * * @param targetFile the file for which the directories are required. Index: src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java =================================================================== RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java,v retrieving revision 1.35 diff -u -r1.35 TraXLiaison.java --- src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java 9 Mar 2004 16:48:15 -0000 1.35 +++ src/main/org/apache/tools/ant/taskdefs/optional/TraXLiaison.java 6 Mar 2005 08:39:30 -0000 @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.net.URI; import java.util.Vector; import java.util.Enumeration; import javax.xml.parsers.ParserConfigurationException; @@ -430,4 +431,32 @@ setOutputProperty(prop.getName(), prop.getValue()); } } + + /** + * Get the stylesheet for an xml source file from its "xml-stylesheet" + * processing instruction + * + * @param xmlFile the xml source file in question + * @return the stylesheet file + */ + public File getStylesheet(File xmlFile) + throws BuildException { + File xslFile = null; + Source xmlSource = new StreamSource(xmlFile); + Source xslSource; + + try { + xslSource = getFactory().getAssociatedStylesheet( + xmlSource, null, null, null); + if (xslSource == null) { + throw new TransformerConfigurationException( + "no matching \"xml-stylesheet\" processing instruction"); + } + xslFile = new File((new URI(xslSource.getSystemId())).getPath()); + } + catch (Exception e) { + throw new BuildException(e); + } + return xslFile; + } } -- Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]