Translate HTML or XML character references to UTF-8.

    Removes HTML or XML character references and entities from a text string
    and replaces them with their UTF-8 representation, if possible.

    :param text: The HTML (or XML) source text.
    :type text: string

    :param skip: list of entity names to skip when transforming.
    :type skip: iterable

    :return: The plain text, as a Unicode string, if necessary.
    @author: Based on http://effbot.org/zone/re-sub.htm#unescape-html

def xml_entities_to_utf8(text, skip=('lt', 'gt', 'amp')):
    """Translate HTML or XML character references to UTF-8.

    Removes HTML or XML character references and entities from a text string
    and replaces them with their UTF-8 representation, if possible.

    :param text: The HTML (or XML) source text.
    :type text: string

    :param skip: list of entity names to skip when transforming.
    :type skip: iterable

    :return: The plain text, as a Unicode string, if necessary.
    @author: Based on http://effbot.org/zone/re-sub.htm#unescape-html
    """
    def fixup(m):
        text = m.group(0)
        if text[:2] == "&#":
            # character reference
            try:
                if text[:3] == "&#x":
                    return unichr(int(text[3:-1], 16)).encode("utf-8")
                else:
                    return unichr(int(text[2:-1])).encode("utf-8")
            except ValueError:
                pass
        else:
            # named entity
            if text[1:-1] not in skip:
                try:
                    text = unichr(
                        html_entities.name2codepoint[text[1:-1]]) \
                        .encode("utf-8")
                except KeyError:
                    pass
        return text  # leave as is
    return re.sub("&#?\w+;", fixup, text)