1 #!/usr/bin/env python 2 3 """ 4 XSL output classes and functions. 5 """ 6 7 # NOTE: Make this use other implementations, too. 8 9 import libxslt 10 import libxml2dom 11 12 class OutputError(Exception): 13 pass 14 15 class Processor: 16 17 """ 18 A handler which can prepare output for an XMLTools2 template. 19 """ 20 21 def __init__(self, filenames, references=None): 22 23 """ 24 Initialise the handler with the 'filenames' of stylesheets producing the 25 final output, a 'references' dictionary indicating related stylesheets. 26 """ 27 28 self.references = references or {} 29 30 # Remember the stylesheet documents. 31 32 self.stylesheets = [] 33 for filename in filenames: 34 self.stylesheets.append(libxslt.parseStylesheetFile(filename)) 35 36 def __del__(self): 37 38 """ 39 Tidy up the stylesheet documents. 40 """ 41 42 for stylesheet in self.stylesheets: 43 stylesheet.freeStylesheet() 44 45 def send_output(self, stream, encoding, document): 46 47 """ 48 Send output to the given 'stream' using the given output encoding for 49 the given 'document'. 50 """ 51 52 result = self._get_result(document) 53 54 if result is not None: 55 # Since result is a native node, use the serialize method. 56 stream.write(result.serialize(encoding)) 57 result.freeDoc() 58 else: 59 raise OutputError, "Transformation failed." 60 61 def get_result(self, document): 62 63 """ 64 Return a transformed document produced from the object's stylesheets and 65 the given 'document'. 66 """ 67 68 result = self._get_result(document) 69 70 if result is not None: 71 return libxml2dom.Node(result) 72 else: 73 raise OutputError, "Transformation failed." 74 75 def _get_result(self, document): 76 77 """ 78 Return a transformation of the given 'document'. 79 """ 80 81 if hasattr(document, "as_native_node"): 82 document = document.as_native_node() 83 84 # Transform the localised instance into the final output. 85 86 parameters = {} 87 for name, reference in self.references.items(): 88 parameters[name.encode("utf-8")] = ("document('%s')" % reference).encode("utf-8") 89 90 last_result = document 91 for stylesheet in self.stylesheets: 92 result = stylesheet.applyStylesheet(last_result, parameters) 93 if last_result is not None: 94 if last_result != document: 95 last_result.freeDoc() 96 last_result = result 97 else: 98 raise OutputError, "Transformation failed." 99 100 return result 101 102 # vim: tabstop=4 expandtab shiftwidth=4