def transform(source, transforms, params=None, output=None): """ Convenience function for applying an XSLT transform. Returns a result object. source - XML source document in the form of a string (not Unicode object), file-like object (stream), file path, URI or amara.lib.inputsource instance. If string or stream it must be self-contained XML (i.e. not requiring access to any other resource such as external entities or includes) transforms - XSLT document (or list thereof) in the form of a string, stream, URL, file path or amara.lib.inputsource instance params - optional dictionary of stylesheet parameters, the keys of which may be given as unicode objects if they have no namespace, or as (uri, localname) tuples if they do. output - optional file-like object to which output is written (incrementally, as processed) """ #do the imports within the function: a tad bit less efficient, but #avoid circular crap from amara.lib import inputsource from amara.xpath.util import parameterize from amara.xslt.result import streamresult, stringresult from amara.xslt.processor import processor params = parameterize(params) if params else {} proc = processor() if isinstance(transforms, (list, tuple)): for transform in transforms: proc.append_transform(inputsource(transform)) else: proc.append_transform(inputsource(transforms)) if output is not None: result = streamresult(output) else: result = stringresult() return proc.run(inputsource(source), params, result)
def _run(self, node, parameters=None, result=None): """ Runs the stylesheet processor against the given XML DOM node with the stylesheets that have been registered. It does not mutate the source. If writer is given, it is used in place of the default output method decisions for choosing the proper writer. """ #QUESTION: What about ws stripping? #ANSWER: Whitespace stripping happens only in the run*() interfaces. # This method is use-at-your-own-risk. The XSLT conformance of the # source is maintained by the caller. This exists as a performance # hook. parameters = parameters or {} self.attributeSets = {} self.keys = {} #See f:chain-to extension element self.chainTo = None self.chainParams = None if not self.transform: raise XsltError(XsltError.NO_STYLESHEET) # Use an internal result to gather the output only if the caller # didn't supply other means of retrieving it. if result is None: result = stringresult() result.parameters = self.transform.output_parameters assert result.writer # Initialize any stylesheet parameters initial_variables = parameters.copy() for name in parameters: if name not in self.transform.parameters: del initial_variables[name] # Prepare the stylesheet for processing context = xsltcontext.xsltcontext(node, variables=initial_variables, transform=self.transform, processor=self, extfunctions=self._extfunctions, output_parameters=result.parameters) context.add_document(node, node.xml_base) context.push_writer(result.writer) self.transform.root.prime(context) # Process the document try: self.transform.apply_templates(context, [node]) except XPathError, e: raise instruction = context.instruction strerror = str(e) e.message = MessageSource.EXPRESSION_POSITION_INFO % ( instruction.baseUri, instruction.lineNumber, instruction.columnNumber, instruction.nodeName, strerror) raise