Re: xslt-process modifications
Brought to you by:
ovidiu
From: Ovidiu P. <ov...@xe...> - 2001-05-13 12:33:35
|
This is a great idea, thanks you for coming up with it! I currently work on the next major release for the code, which has dramatical changes in the source code. I've registered the project at Sourceforge.net, http://sourceforge.net/projects/xslt-process/. Please check out the new source code in the CVS repository (sorry, there is no .tar.gz package for the new code yet). For this new release I was planning to add such a functionality, by giving the option of registering XSLT files. Your approach seems a lot better though because it allows one to run the XSLT processor while editing an XML buffer. So to merge the two approaches, I am thinking of the following: - while visiting an XML or XSLT file, you can use the "XSLT" -> "Register XSLT stylesheet" menu item to register an XSLT file, with the default XSLT file chosen from existing buffers. The registered XSLT stylesheets can then be saved in the options file .emacs persistently. - after you registered the XSLT file, you visit an XML file. If the file has no xml-stylesheet PI, you can associate an XSLT stylesheet to be used using the menu "XSLT" -> "Apply XSLT stylesheet" -> "<stylesheet name>". You need to do the association only once, the association is remembered by Emacs for further invocations. If you want to associate a different XSLT file, you simply select it from the menu. - if the above steps did not happen prior to invoking the processor on an XML file, emacs asks you for the XSLT file to be used and associates it with the XML file. Further invocations of the XSLT processor use the same XSLT file. - when you visit an XSLT buffer and you invoke the XSLT processor, you're asked for an XML buffer on which the XSLT stylesheet should be applied, exactly as in your approach. Does this make sense? What do you think? Regards, Ovidiu On Fri, 11 May 2001 13:16:11 -0500, Matthew Conway <mat...@i2...> wrote: > > Hi, > > I started using your xslt-process, and it works great. Thanks for > making it available. Unfortunately, most of the xml files I process > never have a xsl-stylesheet directive, so adding one when I needed to > process it was becoming a pain. Thus I hacked together a little > something based on your code in order to read in a xsl (or xml) file > from the minibuffer. The prompting works such that a reasonable > default is chosen by examining the filenames of visible xml buffers. > Thus, if I have both a xml and a xsl file open, and I run > xslt-process-invoke in either of them, I only get prompted for a > single file, and the prompt has a default value of the other buffer. > I also hacked up Xalan1.java to use both values always, and never look > for the stylesheet directive, but seeing as how this is probably not > what you want, feel free to ignore those changes! Hope this helps, > > Matt > mat...@i2... > > > (defun xslt-process-is-xml-buffer (buffer) > "Determines if a buffer is xml" > (save-excursion > (set-buffer buffer) > (string= mode-name "XML"))) > > (defun xslt-process-get-xml-buffers () > "Get a list of the xml buffers open in the > current session." > (mapcan (lambda (buffer) > (if (xslt-process-is-xml-buffer buffer) > (list buffer))) > (buffer-list))) > > (defun xslt-process-get-visible-xml-buffers () > "Returns a list of visible xml buffers." > (delq > nil > (mapcar > (lambda (buffer) > (if (get-buffer-window buffer 'visible) buffer)) > (xslt-process-get-xml-buffers)))) > > (defun xslt-process-read-file (prompt) > "Reads a filename, using a any other visible xml buffer as a default" > (let* ((buffer (car > (delete (current-buffer) (xslt-process-get-visible- > xml-buffers)))) > (default-filename (buffer-file-name buffer))) > (read-file-name (concat prompt " (" default-filename "): ") "" default-filename))) > > (defun xslt-process-read-files-to-process () > "Returns list of (xmlfile xslfile) for invoke to operate on" > (let* ((currentfile (buffer-file-name)) > (isXmlFile (if currentfile (string-match "\.xml$" currentfile))) > (isXslFile (if currentfile (string-match "\.xsl$" currentfile)))) > > (list (if (or isXslFile (not (or isXmlFile isXslFile))) > (xslt-process-read-file "XML file to process") > (expand-file-name currentfile)) > (if (or isXmlFile (not (or isXmlFile isXslFile))) > (xslt-process-read-file "Stylesheet to use") > (expand-file-name currentfile))))) > > (defun xslt-process-invoke (&optional xmlFile xslFile) > "This is the main function which invokes the XSLT processor of your > choice on the current buffer." > (interactive (xslt-process-read-files-to-process)) > (let* ((temp-directory > (or (if (fboundp 'temp-directory) (temp-directory)) > (if (boundp 'temporary-file-directory) temporary-file-directory)) > ) > (classpath > (if (boundp 'jde-global-classpath) > jde-global-classpath > nil)) > (classpath-env (if (getenv "CLASSPATH") > (split-string (getenv "CLASSPATH") > jde-classpath-separator) > nil)) > (out-buffer (get-buffer-create "*xslt output*")) > (msg-buffer (get-buffer-create "*xslt messages*")) > (xslt-jar (concat > (xslt-process-find-xslt-directory) "java/xslt.jar")) > (tmpfile (make-temp-name (concat temp-directory "/xsltout"))) > ; Set the name of the XSLT processor. This is either specified > ; in the local variables of the file or is the default one. > (xslt-processor > (progn > ; Force evaluation of local variables > (hack-local-variables t) > (or > (if (and > (local-variable-p 'processor (current-buffer)) > (boundp 'processor)) > (if (stringp processor) > processor > (symbol-name processor))) > (symbol-name (car xslt-process-default-processor)))))) > (save-excursion > ; Reset any local variables in the source buffer so the next > ; time we execute we correctly pick up the default processor > ; even if the user decides to remove the local variable > (makunbound 'processor) > ; Prepare to invoke the Java method to process the XML document > (setq jde-global-classpath > (mapcar 'expand-file-name > (union (append jde-global-classpath (list xslt-jar)) > (union xslt-process-additional-classpath > classpath-env)))) > ; Append the additional arguments to the arguments passed to bsh > (setq bsh-vm-args (union xslt-process-jvm-arguments bsh-vm-args)) > ; Setup additional arguments to the processor > (setq func (get (intern-soft xslt-processor) 'additional-params)) > (if (not (null func)) (funcall func)) > ; Prepare the buffers > (save-some-buffers) > (set-buffer msg-buffer) > (erase-buffer) > (set-buffer out-buffer) > (erase-buffer) > ; Invoke the processor, displaying the result in a buffer and > ; any error messages in an additional buffer > (condition-case nil > (progn > (setq messages (bsh-eval > (concat "xslt." xslt-processor ".invoke(\"" > xmlFile "\", \"" xslFile > "\", \"" tmpfile "\");"))) > (setq jde-global-classpath classpath) > (if (file-exists-p tmpfile) > (progn > (set-buffer out-buffer) > (insert-file-contents tmpfile) > (delete-file tmpfile) > (display-buffer out-buffer) > (if (not (string= messages "")) > (xslt-process-display-messages messages > msg-buffer out-buffer)) > (message "Done invoking %s." xslt-processor)) > (message (concat "Cannot process " > (file-name-nondirectory xmlFile) ".")) > (xslt-process-display-messages messages msg-buffer out-buffer))) > (error (progn > (message > (concat "Could not process file, most probably " > xslt-processor > " could not be found!")) > (message (concat "Failed to process: " xmlFile " with: " xslFile)) > (setq jde-global-classpath classpath))))))) > > > package xslt; > > import org.apache.xalan.xslt.XSLTProcessorFactory; > import org.apache.xalan.xslt.XSLTProcessor; > import org.apache.xalan.xslt.XSLTInputSource; > import org.w3c.dom.Node; > import org.w3c.dom.NamedNodeMap; > import org.apache.xalan.xslt.XSLTResultTarget; > import org.w3c.dom.ProcessingInstruction; > import java.util.Hashtable; > import java.util.StringTokenizer; > import java.net.URL; > import java.io.File; > import java.io.InputStream; > import java.io.FileOutputStream; > import java.io.FileInputStream; > > public class Xalan1 > { > public static void invoke(String xmlFilename, String xslFilename, String outFilename) > { > try > { > File xmlFile = new File(xmlFilename); > File xslFile = new File(xslFilename); > if ( !xmlFile.exists() ) > { > System.out.println("Cannot find xml file: " + xmlFilename); > return; > } > > if ( !xslFile.exists() ) > { > System.out.println("Cannot find xsl file: " + xslFilename); > return; > } > > XSLTProcessor processor = XSLTProcessorFactory.getProcessor(); > XSLTInputSource xmlDoc = new XSLTInputSource(new FileInputStream(xmlFile)); > XSLTInputSource xslDoc = new XSLTInputSource(new FileInputStream(xslFile)); > FileOutputStream out = new FileOutputStream(outFilename); > > // Finally process the XML document through the XSLT processor > processor.process(xmlDoc, xslDoc, new XSLTResultTarget(out)); > out.close(); > } > catch(Exception e) { > System.out.println("Cannot process: " + e); > } > } > > } > > |