1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/XSLTools/XSLOutput.py Thu Aug 18 15:57:28 2005 +0000
1.3 @@ -0,0 +1,126 @@
1.4 +#!/usr/bin/env python
1.5 +
1.6 +"""
1.7 +XSL output classes and functions.
1.8 +
1.9 +Copyright (C) 2005 Paul Boddie <paul@boddie.org.uk>
1.10 +
1.11 +This library is free software; you can redistribute it and/or
1.12 +modify it under the terms of the GNU Lesser General Public
1.13 +License as published by the Free Software Foundation; either
1.14 +version 2.1 of the License, or (at your option) any later version.
1.15 +
1.16 +This library is distributed in the hope that it will be useful,
1.17 +but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.19 +Lesser General Public License for more details.
1.20 +
1.21 +You should have received a copy of the GNU Lesser General Public
1.22 +License along with this library; if not, write to the Free Software
1.23 +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.24 +"""
1.25 +
1.26 +# NOTE: Make this use other XSLT implementations, too.
1.27 +
1.28 +import libxsltmod
1.29 +import libxml2dom
1.30 +
1.31 +class OutputError(Exception):
1.32 + pass
1.33 +
1.34 +class Processor:
1.35 +
1.36 + """
1.37 + A handler which can prepare output for an XMLTools2 template.
1.38 + """
1.39 +
1.40 + def __init__(self, filenames, references=None, parameters=None):
1.41 +
1.42 + """
1.43 + Initialise the handler with the 'filenames' of stylesheets producing the
1.44 + final output, a 'references' dictionary indicating related stylesheets.
1.45 + Additional 'parameters' may also be specified as a dictionary.
1.46 + """
1.47 +
1.48 + self.references = references or {}
1.49 + self.parameters = parameters or {}
1.50 +
1.51 + # Remember the stylesheet documents.
1.52 +
1.53 + self.stylesheets = []
1.54 + for filename in filenames:
1.55 + doc = libxml2dom.macrolib.parseFile(filename)
1.56 + self.stylesheets.append(libxsltmod.xsltParseStylesheetDoc(doc))
1.57 +
1.58 + def __del__(self):
1.59 +
1.60 + """
1.61 + Tidy up the stylesheet documents.
1.62 + """
1.63 +
1.64 + for stylesheet in self.stylesheets:
1.65 + libxsltmod.xsltFreeStylesheet(stylesheet)
1.66 +
1.67 + def send_output(self, stream, encoding, document):
1.68 +
1.69 + """
1.70 + Send output to the given 'stream' using the given output encoding for
1.71 + the given 'document'.
1.72 + """
1.73 +
1.74 + result = self.get_result(document)
1.75 +
1.76 + if result is not None:
1.77 + stream.write(result.toString(encoding))
1.78 + else:
1.79 + raise OutputError, "Transformation failed."
1.80 +
1.81 + def get_result(self, document):
1.82 +
1.83 + """
1.84 + Return a transformed document produced from the object's stylesheets and
1.85 + the given 'document'.
1.86 + """
1.87 +
1.88 + result = self._get_result(document)
1.89 +
1.90 + if result is not None:
1.91 + return libxml2dom.adoptNodes([result])[0]
1.92 + else:
1.93 + raise OutputError, "Transformation failed."
1.94 +
1.95 + def _get_result(self, document):
1.96 +
1.97 + """
1.98 + Return a transformation of the given 'document'.
1.99 + """
1.100 +
1.101 + if hasattr(document, "as_native_node"):
1.102 + document = document.as_native_node()
1.103 +
1.104 + # Transform the localised instance into the final output.
1.105 +
1.106 + parameters = {}
1.107 + for name, reference in self.references.items():
1.108 + parameters[name.encode("utf-8")] = ("document('%s')" % self._quote(reference)).encode("utf-8")
1.109 + for name, parameter in self.parameters.items():
1.110 + parameters[name.encode("utf-8")] = ("'%s'" % self._quote(parameter)).encode("utf-8")
1.111 + #print "**", repr(parameters)
1.112 +
1.113 + last_result = document
1.114 + for stylesheet in self.stylesheets:
1.115 + result = libxsltmod.xsltApplyStylesheet(stylesheet, last_result, parameters)
1.116 + if last_result is not None:
1.117 + last_result = result
1.118 + else:
1.119 + raise OutputError, "Transformation failed."
1.120 +
1.121 + return result
1.122 +
1.123 + def _quote(self, s):
1.124 +
1.125 + "Make the given parameter string 's' palatable for libxslt."
1.126 +
1.127 + return s.replace("'", "%27")
1.128 +
1.129 +# vim: tabstop=4 expandtab shiftwidth=4