html/xml Entityfier und Deentitifier

Code-Stücke können hier veröffentlicht werden.
Antworten
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo zusammen,

hab mal wieder ein kleines und wie ich finde sehr brauchbares Modul gebastelt:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
    Modul:          Entities
    Description:    Entitify and Deentitfy Specialchars for html/xml
    Version:        0.2
    Copyright:      2004 by Fritz Cizmarov fritz@sol.at
    Created:        29. Jul. 2004
    Last modified:  29. Jul. 2004
    License:        free
    Requirements:   Python2.3
    Exports:        Entities, entitify, deentitify
"""

import re
from array import array

_c2n = {34 : "quot", 38 : "amp", 39 : "apos", 60 : "lt", 62 : "gt"}
_n2c = {"quot" : 34, "amp" : 38, "apos" : 39, "lt" : 60, "gt" : 62}

_regex = re.compile(r"&([#\w]+);", flags=re.UNICODE) # find entities


class Entities(object):
    """ Pseudomapping of entities """
    
    __slots__ = ["n2c","ukh"]
    
    def __init__(self, n2c={}, handle_unknown=lambda key: u"&%s;" % key ):
        super(Entities, self).__init__()
        self.n2c = n2c
        self.ukh = handle_unknown # standart restore entity
        
    def __getitem__(self, key):
        """ calculate unicode or get it from n2c """
        if key[0] == "#":   # numeric value
            if key[1] in "xX":  # hexadecimal
                return unichr(int(key[2:], 16))
            else:               # decimal
                return unichr(int(key[1:]))
        else: # named Entity
            try:
                return unichr(self.n2c[key])
            except KeyError:
                return self.ukh(key)


def entitify(ustring, c2n=_c2n):
    """ convert unicodestring to string with entities """
    tmp = array('c')
    if not isinstance(ustring, unicode):
        raise TypeError ("argument musst be unicode")
    for char in ustring: 
        cc = ord(char)
        if ( not (32 <= cc <= 127)) or c2n.has_key(cc):
            tmp.fromstring("&%s;" % c2n.get(cc, "#x%x" % cc))
        else: # simple ascii and not specialchar
            tmp.append(chr(cc))
    return tmp.tostring()


def deentitify(string, n2c=_n2c):
    """ convert string with entities to unicodestring """
    return _regex.sub(r"%(\1)s", string) % Entities(n2c)


if __name__ == "__main__":
    from htmlentitydefs import name2codepoint, codepoint2name
    import sys
    if len(sys.argv) < 2:
        print "usage: %s <string>"
        sys.exit()
    string = sys.argv[1]
    if _regex.search(string): # has entities?
        print deentitify(string, name2codepoint)
    else:
        print entitify(string.decode(sys.getfilesystemencoding()),
                       codepoint2name)
Beispiel:

Code: Alles auswählen

fritz@seneca:~/Python/module$ Entities.py "Umlaute äöüßÄÖÜ und Euro €"
Umlaute äöüßÄÖÜ und Euro €
fritz@seneca:~/Python/module$ Entities.py "Umlaute äöüßÄÖÜ und Euro €"
Umlaute äöüßÄÖÜ und Euro €

entitify erwartet einen Unicodestring und wandelt diesen in einen String (nicht Unicode!) mit den Sonderzeichen als html/xml-Entities.
deentitify erwartet einen String mit Entities und wandelt diese in einen Unicodestring mit den entsprechenden Sonderzeichen


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo nochmal,

ich hab obigen Code nochmal überbearbeitet, jetzt werden standartmässig nur die in xml erlaubten entities lt, gt, amp, quot, apos in Entities mit Namen umgewandelt, alle anderen Sonderzeichen mit ASCII-Codes < 32 und > 127 werden als numerische Entities eingetragen.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi Dookie!

:D Dieses Codebeispiel von dir hätte ich gestern brauchen können, dann hätte ich mir ca. zwei Stunden Arbeit erspart. :wink:

Vielen Dank für deine Beiträge in diesem Forum,
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
genrich
User
Beiträge: 91
Registriert: Sonntag 27. Juni 2004, 17:46

Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi genrich,

nicht ganz, neben < > und & werden auch Unicodezeichen < 32 und > 127 mit meiner Routine als numerische Entities escaped.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Antworten