You are here: Partenza > Dive Into Python > Elaborare XML > Unicode | << >> | ||||
Dive Into PythonPython per programmatori esperti |
Unicode è un sistema per rappresentare i caratteri di tutti i differenti linguaggi del mondo. Quando Python analizza un documento XML, tutti i dati sono immagazzinati in memoria sottoforma di unicode.
Sarà spiegato tutto fra un minuto, ma prima, una piccola introduzione.
Nota storica. Prima dell'unicode, esistevano sistemi di codifica dei caratteri separati per ogni linguaggio, ognuno usava gli stessi numeri (0-255) per rappresentare i caratteri di quel linguaggio. Alcuni (come il russo) avevano multipli standard, in conflitto sul modo di rappresentare lo stesso carattere; altri linguaggi (come il giapponese) avevano così tanti caratteri che richiedevano numerosi set di caratteri. Lo scambio di documenti fra i sistemi era difficile perché non c'era modo per un computer di dire quale schema di codifica dei caratteri avesse usato l'autore del documento; il computer vedeva solo numeri ed i numeri potevano significare cose differenti. Perciò pensate di porre questi documenti nel medesimo luogo (ad esempio la stessa tabella di un database); avreste bisogno di registrare la codica dei caratteri per ogni parte del testo ed essere sicuri di fornirla insieme allo stesso. Quindi pensate a documenti multilingue, con caratteri provenienti da vari linguaggi nello stesso documento. Solitamente questi utilizzano caratteri di escape per cambiare il modo di codifica; usiamo il modo russo koi8-r, perciò il carattere 241 indica questo; adesso usiamo il Greco del Mac, perciò il carattere 241 indica qualcos'altro. E così via. Questi sono i problemi per i quali l'unicode è stato ideato.
Per risolvere questi problemi, l'unicode rappresenta ogni carattere come un numero di 2 byte, da 0 a 65535. [11] Ogni numero di 2 byte rappresenta un unico carattere usato in almeno uno dei linguaggi del mondo. Caratteri che sono usati in molteplici linguaggi hanno lo stesso codice numerico. C'è esattamente 1 numero per carattere ed esattamente un carattere per numero. I dati unicode non sono mai ambigui.
Ovviamente c'è ancora il problema di tutte queste eredità dei sistemi di codifica. L'ASCII a 7 bit, per esempio, registra i caratteri inglesi come numeri da 0 a 127. (65 è la “A” maiuscola, 97 è la “a minuscola” e così via.) L'inglese ha un alfabeto molto semplice, perciò può essere espresso completamente tramite l'ASCII a 7 bit. I linguaggi dell'ovest europeo come il francese, lo spagnolo e il tedesco (e l'italiano N.d.T.) usano tutti una codifica dei caratteri chiamata ISO-8859-1 (“latin-1”), per i numeri da 0 al 127 ma vengono estesi nel gruppo di caratteri dal 128 al 255 come la “n con la tilde sopra”(241), o la “u con due punti sopra”(252). L'unicode utilizza gli stessi caratteri dell'ASCII a 7 bit per i numeri dallo 0 al 127 e gli stessi caratteri dell'ISO-8859-1 per i numeri da 128 a 255, estende da quel punto in poi, tutti i caratteri per gli altri linguaggi con i numeri rimanenti, da 256 a 65535.
Quando vi occupate dei dati unicode, potreste aver bisogno, in alcuni punti, di convertire i dati in una delle altre codifiche dei caratteri descritte. Per esempio, per integrarli con qualche altro sistema che si aspetta dei dati in uno schema di codifica specifico ad 1 byte o stamparlo da un terminale o da una stampante non unicode. Oppure immagazzinarli in un documento XML che esplicita specificatamente lo schema di codifica.
E dopo questa nota, torniamo al Python.
Python supporta l'unicode nativamente sin dalla versione 2.0. [12] Il pacchetto XML usa l'unicode per registrare tutti i dati XML analizzati, ma potete usare l'unicode ovunque.
>>> s = u'Dive in' >>> s u'Dive in' >>> print s Dive in
>>> s = u'La Pe\xf1a' >>> print s Traceback (innermost last): File "<interactive input>", line 1, in ? UnicodeError: ASCII encoding error: ordinal not in range(128) >>> print s.encode('latin-1') La Peña
Ricordate quando dissi che Python solitamente convertiva unicode in ASCII, ovunque occorresse creare una stringa regolare da una unicode? Bene, questo schema di codifica predefinito è un'opzione che potete personalizzare.
# sitecustomize.py # this file can be anywhere in your Python path, # but it usually goes in ${pythondir}/lib/site-packages/ import sys sys.setdefaultencoding('iso-8859-1')
>>> import sys >>> sys.getdefaultencoding() 'iso-8859-1' >>> s = u'La Pe\xf1a' >>> print s La Peña
E riguardo l'XML? Bene, ogni documento XML contiene una codifica specifica. ISO-8859-1 è una popolare codifica per dati nei linguaggi dell'ovest europeo. KOI8-R è comune nei testi russi. La codifica, se specificata, si trova nell'header del documento XML.
<?xml version="1.0" encoding="koi8-r"?> <preface> <title>Предисловие</title> </preface>
>>> from xml.dom import minidom >>> xmldoc = minidom.parse('russiansample.xml') >>> title = xmldoc.getElementsByTagName('title')[0].firstChild.data >>> title u'\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435' >>> print title Traceback (innermost last): File "<interactive input>", line 1, in ? UnicodeError: ASCII encoding error: ordinal not in range(128) >>> convertedtitle = title.encode('koi8-r') >>> convertedtitle '\xf0\xd2\xc5\xc4\xc9\xd3\xcc\xcf\xd7\xc9\xc5' >>> print convertedtitle Предисловие
Per riassumere, unicode stesso è un pò intimidente se non lo avete mai visto prima, ma i dati unicode sono veramente facili da gestire in Python. Se i vostri documenti XML sono tutti in ASCII a 7 bit (come gli esempi in questo capitolo) non avrete mai bisogno di pensare all'unicode. Python convertirà i dati ASCII nel documento XML in unicode, durante il parsing, ed auto-convertirà in ASCII ogniqualvolta sarà necessario, non ve ne accorgerete neanche. Ma se avete bisogno di occuparvi di dati in altre lingue, Python è pronto.
[11] Questo, tristemente, è ancora una semplificazione. Unicode ora è stato esteso per gestire testi in Cinese antico, in Coreano ed in Giapponese, che hanno talmente tanti caratteri diversi che il sistema unicode a 2 byte non li potrebbe rappresentare tutti. Ma Python attualmente non supporta tutto questo, e non so se ci sia qualche progetto che permetta di estenderlo in tale senso. Spiacente, avete raggiunto i limiti della mia conoscenza.
[12] Python ha il supporto per unicode dalla versione 1.6, ma la versione 1.6 era un obbligo contrattuale di cui nessuno ama parlare, un figliastro da dimenticare. Anche la documentazione ufficiale di Python dichiara che unicode è “nuovo nella versione 2.0”. È una bugia ma, come le bugie dei presidenti che dicono di aver fumato ma che non gli è piaciuto, scegliamo di crederci perché ricordiamo la nostra giovinezza mal spesa in maniera fin troppo vivida.
<< Analizzare XML |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | |
Ricercare elementi >> |