[Python-de] XML-Codierung

Andreas Grytz agrytz at linux-user.de
Mit Dez 17 16:53:14 CET 2003


Hallo zusammen,

hier ist schon einige Male über die Problematik von verschiedenen
Encondings diskutiert worden. Ich möchte diese Diskussion nicht wieder
aufwärmen, bin aber in eine Schwierigkeit geraten, die damit zu tun hat.

Angehängt sind ein Skript, dass mittels xml.sax ein XML-Format
verarbeiten soll. Klappt auch soweit ganz gut, wenn keine Sonderzeichen
drin sind.

Folgende Fehlermeldung bekommt man derzeit, weil ein Umlaut im Text zu
finden ist:

Traceback (most recent call last):
  File "./news-parser.py", line 78, in ?
    handler.test_output()
  File "./news-parser.py", line 67, in test_output
    self._out.write("%s\n".encode(self.encoding) % self.body)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in \
	position 103: ordinal not in range(128)

Ich wollte im wesentlichen mal fragen, welche Texte im Web den zur
Einführung in die Problematik geeignet sind.

Im wesentlichen verstehe ich die Meldung so, dass versucht wird ein
Unicode-Zeichen in ein ASCII-Zeichen umzuwandeln, es befindet sich
allerdings außerhalb der ersten 128 Zeichen des 7-Bit
ASCII-Zeichensatzes und ist deshalb nicht darstellbar.

Schoenen Gruss,

Andreas

-- 
Andreas Grytz		| http://www.linuxnewmedia.de
Stefan-George-Ring 24	| Tel:	+49 (0) 89 993411-0
D-81929 München		| Fax:	+49 (0) 89 993411-99
-------------- nächster Teil --------------
#!/usr/bin/python

import sys
import string
import xml.sax
from xml.sax import ContentHandler

file = sys.argv[1]

class NewsHandler(ContentHandler):

	def __init__(self, out=sys.stdout, encoding="iso-8859-1"):
		self.intitle = 0
		self.inbody = 0
		self.ina = 0
		self.body = ""
		self.encoding = encoding
		self.url = 0
		self.href = []
		self._out = out

	def startDocument(self):
		pass

	def endDocument(self):
		pass

	def startElement(self, name, attrs):
		if name == "news":
			self.editor = attrs['editor']
		elif name == "title":
			self.intitle = 1
		elif name == "a":
			self.url = self.url + 1
			self.href.append(attrs['href'])
			self.ina = 1
		elif name == "p":
			self.inbody = 1
			self.body = self.body + "\n<p>\n"

	def endElement(self, name):
		if name == "title":
			self.intitle = 0
		elif name == "a":
			if len(self.anchor):
				self.body = self.body + "%s[%d]" % (self.anchor, self.url)
			else: self.body = self.body + "%s [%d]" % (self.href[self.url], self.url)
			self.ina = 0
		elif name == "p":
			self.body = self.body + "\n</p>"
			self.inbody = 0
		elif name == "news":
			pass

	def characters(self, content):
		if self.intitle:
			self.title = content
		elif self.ina:
			self.anchor = content
		elif self.inbody:
			self.body = self.body + string.replace(content, '\n', ' ')

	def test_output(self):
		self._out.write(len(self.title) * "-" + "\n")
		self._out.write("%s\n".encode(self.encoding) % self.title)
		self._out.write(len(self.title) * "-" + "\n")
		self._out.write("%s\n".encode(self.encoding) % self.body)
		self._out.write((len(self.href[0])+ 5) * "-" + "\n")
		for url in self.href:
			self._out.write("[%d] %s\n" % (self.href.index(url)+1, url))

if  __name__=='__main__':

	parser = xml.sax.make_parser()
	handler = NewsHandler()
	parser.setContentHandler(handler)
	parser.parse(file)
	handler.test_output()
-------------- nächster Teil --------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<news editor="agr">
<title>19-Zoll-Server im Mini-Format</title>

<p>Ab Januar hat der Distributor <a href="http://www.ipc2u">IPC2U</a>
einen besonders kleinen 19-Zoll-Server im Programm. Das Gehäuse
benoetigt eine Hoeheneinheit bei voller Frontbreite und nur 25
Zentimetern Tiefe. Damit lassen sich Standard-19-Zoll-Schraenke mit bis
zu 96 dieser Mini-Server bestuecken, wenn Vorder- und Rueckseite des
Schranks verwendet werden.</p>

<p>Die Platzverhaltnisse im Gehaeuse sind den Abmessungen entsprechend
stark eingeschraenkt. So laesst sich zum Beispiel keine PCI-Karte
nachruesten, der <a href="http://www.platz.de">Platz</a> ist fur die
3,5-Zoll-Festplatte sowie ein Slimline-CD-ROM reserviert. Der Preis
wird voraussichtlich 470 Euro betragen fuer einen Server mit Via
Epia-1000 und einer 40-GByte-Festplatte.</p>
</news>