ecoxipy.transformation - Transforming XML

This module provides an XML transformation API. It containes the abstract ecoxipy.Output implementation MarkupTransformer, which does on-the-fly transformations while creating XML with the wrapped output instance. Implementations of this class are used as output of ecoxipy.MarkupBuilder instances. Instances of PyXOMTransformer transform ecoxipy.pyxom data structures in-place. The methods of implementations of these classes can be annotated with the decorators in MATCH to serve as transformation callables – if a transformation is the first who’s test matches, it is applied and transformation is finished. If no transformation callable matches, the node is not transformed.

Examples

We define a transformer which does:

  • Elements with an attribute href are converted to a links. If the element is a span, it is directly converted to an a, otherwise the original element is wrapped in an a.
  • Processing instructions with target title are converted to an h1 element and set the instance variable _title.
  • Text nodes with content foo bar are converted to upper case and wrapped into a strong element.
  • All comments are removed.
  • Documents with document type template are converted to a HTML5 document using the instance variable _title.
>>> class MyTransformer(MarkupTransformer):
...     @MATCH.element.test(
...             lambda name, children, attributes: 'href' in attributes)
...     def link(self, name, children, attributes):
...         if name == 'span':
...             return self.B.a(children, attributes)
...         href = attributes.pop('href')
...         return self.B.a(
...             self.B[name](children, attributes), href=href)
...
...     @MATCH.pi.title
...     def foo(self, target, content):
...         self._title = content
...         return self.B.h1(content)
...
...     @MATCH.text('foo bar')
...     def foo_bar(self, content):
...         return self.B.strong(content.upper())
...
...     @MATCH.comment()
...     def comment(self, content):
...         pass
...
...     @MATCH.document.template
...     def doc(self, *args):
...         B = self.B
...         return B[:'html':True]('\n',
...             B.html('\n',
...                 B.head(B.title(self._title)), '\n',
...                 B.body('\n', args[3], '\n'), '\n',
...             )
...         )

We create an example document, using the transformer:

>>> from ecoxipy import MarkupBuilder
>>> B = MyTransformer.builder()
>>> print(B[:'template':True](
...     B['title':'Test'], '\n',
...     B | 'This comment will be removed.',
...     B.p('\n',
...         B.span('Example Site', href='http://example.com'), '\n',
...         'foo bar', '\n',
...         B.em('Example Site', href='http://example.com', lang='en'), '\n'
...     )
... ))
<!DOCTYPE html>
<html>
<head><title>Test</title></head>
<body>
<h1>Test</h1>
<p>
<a href="http://example.com">Example Site</a>
<strong>FOO BAR</strong>
<a href="http://example.com"><em lang="en">Example Site</em></a>
</p>
</body>
</html>

API

class ecoxipy.transformation.MarkupTransformer(output=None, input_encoding='UTF-8', parser=None)[source]

Base transformer class that implements the ecoxipy.Output interface.

Extend it and annotate your methods with the decorators contained in MATCH. These methods must have a signature compatible with the appropriate methods of ecoxipy.Output, i.e. a method annotated with MATCH.element must conform to ecoxipy.Output.element(). Their return values replace the content otherwise created, if there were no transformation. The methods should use the builder contained in the attribute B to create XML structures, then they are independent of the ecoxipy.Output implementation given on intitialization.

Your class should not override the methods as defined by ecoxipy.Output and the following attributes:

  • B
  • builder
  • default_transformer
  • MATCH_SPEC
  • transformer
  • output
ecoxipy.transformation.MATCH[source]
.element
.text
.comment
.pi
.document

Table Of Contents

Previous topic

ecoxipy.validation - Validating XML

Next topic

ecoxipy.string_output - Building XML Strings