ecoxipy.validation - Validating XML

This module provides the ecoxipy.Output implementation ValidationOutputWrapper, which validates the XML created using a validator object. The class ListValidator is a validator implementation working based on black- or whitelists.

To use validation for markup builders, use instances of this class:

class ecoxipy.validation.ValidationOutputWrapper(output, validator)[source]

Instances of this class wrap an ecoxipy.Output instance and a validator instance, the latter having a method like ecoxipy.Output for each XML node type it wishes to validate (i.e. element(), text(), comment(), processing_instruction() and document()).

When a XML node is to be created using this class, first the appropriate validator method is called. This might raise an exception to stop building completely. If this returns None or True, the result of calling the same method on the output instance is returned. Otherwise the creation call returns None to create nothing.

Note that a validator’s element() method receives the attributes dictionary which is given to the output, thus changes made by a validator are reflected in the created XML representation.

Validators should throw the following exception:

class ecoxipy.validation.ValidationError[source]

Should be raised by validators to indicate a error while validating, the message should describe the problem.

A simple black- or whitelist validator:

class ecoxipy.validation.ListValidator(element_names=None, attribute_names=None, pi_targets=None, blacklist=True, silent=True)[source]

A simple black- or whitelist-based validator class (see ValidationOutputWrapper). It takes lists of element as well as attribute names and processing instruction targets, all given names and targets are converted to Unicode. If the blacklist argument is True the lists define which elements, attributes and processing instructions are invalid. If blacklist is False the instance works as a whitelist, thus the lists define the valid elements, attributes and processing instructions. If the argument silent is True, the validating methods return False on validation errors, otherwise they raise a ValidationError.

Parameters:
  • element_names – An iterable of element names or None to accept all elements.
  • attribute_names – An iterable of attribute names or None to accept all attributes.
  • pi_targets – An iterable of processing instruction targets or None to accept all processing instructions.
  • blacklist (bool) – If this is True, the instance works as a blacklist, otherwise as a whitelist.
  • silent (bool) – If this is True, failed validations return False for invalid element names or processing instruction targets and invalid attributes are deleted. Otherwise they raise a ValidationError.

Examples

First we define a blacklist validator and use it to define a markup builder:

>>> blacklist = ListValidator(['script', 'style'], ['onclick', 'style'], ['xml-stylesheet'])
>>> from ecoxipy import MarkupBuilder
>>> from ecoxipy.string_output import StringOutput
>>> output = ValidationOutputWrapper(StringOutput(), blacklist)
>>> b = MarkupBuilder(output)

Here we create XML, invalid nodes are not created:

>>> print(b.p(
...     b['xml-stylesheet': 'href="BadStyling.css"'],
...     b['my-pi': 'info'],
...     b.script('InsecureCode();'),
...     'Hello ', b.em(
...         'World', {'class': 'important', 'onclick': 'MalicousThings();'}),
...     '!'
... ))
<p><?my-pi info?>Hello <em class="important">World</em>!</p>

And now we define a whitelist validator, which is not silent but raisese exeptions on validation errors:

>>> whitelist = ListValidator(['p', 'em'], ['class'], ['my-pi'], False, False)
>>> output = ValidationOutputWrapper(StringOutput(), whitelist)
>>> b = MarkupBuilder(output)

First we create valid XML, then some invalid XML:

>>> print(b.p(
...     b['my-pi': 'info'],
...     'Hello ', b.em('World', {'class': 'important'}), '!'
... ))
<p><?my-pi info?>Hello <em class="important">World</em>!</p>
>>> try:
...     b['xml-stylesheet': 'href="BadStyling.css"']
... except ValidationError as e:
...     print(e)
The processing instruction target "xml-stylesheet" is not allowed.
>>> try:
...     b.script('InsecureCode();')
... except ValidationError as e:
...     print(e)
The element name "script" is not allowed.
>>> try:
...     b.em('World', {'class': 'important', 'onclick': 'MalicousThings();'})
... except ValidationError as e:
...     print(e)
The attribute name "onclick" is not allowed.

If one of the element, attribute or processing instruction validity lists of ListValidator is None, it allows all nodes of that type:

>>> anything = ListValidator()
>>> output = ValidationOutputWrapper(StringOutput(), anything)
>>> b = MarkupBuilder(output)
>>> print(b.p(
...     b['my-pi': 'info'],
...     'Hello ', b.em('World', {'class': 'important'}), '!'
... ))
<p><?my-pi info?>Hello <em class="important">World</em>!</p>
>>> anything = ListValidator(blacklist=False)
>>> output = ValidationOutputWrapper(StringOutput(), anything)
>>> b = MarkupBuilder(output)
>>> print(b.p(
...     b['my-pi': 'info'],
...     'Hello ', b.em('World', {'class': 'important'}), '!'
... ))
<p><?my-pi info?>Hello <em class="important">World</em>!</p>

Table Of Contents

Previous topic

ecoxipy.parsing - Parsing XML

Next topic

ecoxipy.transformation - Transforming XML