import re


def escape_xml_illegal_chars(val, replacement='?'):
    """Replace illegal XML characters with a user defined value.

    Not all UTF-8 characters are valid XML. This function will strip illegal
    UTF-8 characters to prepare them for XML documents. It will also
    silently ignore 'None' values.

    https://lsimons.wordpress.com/2011/03/17/stripping-illegal-characters-out-of-xml-in-python/
    https://github.com/enthought/Python-2.7.3/blob/master/Lib/plistlib.py#L215

    Args:
        val: Value to filter.
        replacement: Replace invalid character with this value.
    Returns:
        Sanitized value.
"""
    _illegal_xml_chars_RE = re.compile(u'[\x00-\x08\x0b\x0c\x0e-\x1F\uD800-\uDFFF\uFFFE\uFFFF]')

    if val is not None:
        return _illegal_xml_chars_RE.sub(replacement, val)
    else:
        return None