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]

Reply via email to