Perl Webworking

XML::Feed und Unicode

Das Modul XML::Feed soll als API dienen zum transparenten Aufruf und Analyse von RSS-und ATOM-Feeds.
Dabei gibt das Modul die Anfragen je nach Typ des Feeds weiter an die Module XML::RSS und XML::Atom::Feed.

In der Regel funktioniert dies auch sehr schön.

In einem Skript welches Feeds in Webseiten einbinden soll, stellte sich jedoch ein Problem heraus: Trotz Ausgabeformat UTF-8 und der korrekten Setzung des Charsets für den Browser enthielt die Ausgabe vermeintliche Umlaute als ein Zeichensalat.
Dabei kommt es zu der falschen Codierung erst nach dem Aufruf der Methoden $OBJ->title und $OBJ->content->body.

Beispiel:

  foreach my $entry ($feed->entries) {
       print "Titel: ".$entry->title."\\n";
       print "Content: ".$entry->content->body."\\n";
  }

Vor Zuweisung des Inhalts handelte es sich um einen ganz normalen UTF-8-String, wie Kontrollausgaben belegten.

Nach einigen Suchen im Netz wurde ich hier fündig: Perl UTF-8 Hell And How To Find Your Way Out.

Offenbar gehen sowohl XML::RSS als auch XML::Atom::Feed per Default davon aus, daß der eingehende Text in Latin-1 eintrifft.
In dieser Annahme wird dann der Code in UTF-8 umgewandelt, ohne das vorher geprüft wurde, ob es nicht schon UTF-8 ist…
Der Umlaut, der bereits in UTF-8 vorliegt, wird nochmals codiert und somit in ein Sonderzeichen verwandelt, welches wir garnicht wollten.

Damit diese beiden Module dies nicht tun, gibt es entsprechende Flags oder Attribute:

Bei XML::RSS wird bei der Objekterstellung das Encoding angegeben:

my $rss = new XML::RSS (
    'version' => '1.0',
    'encoding' => 'UTF-8',
    'encode_output' => 0
);

Bei XML::ATOM erfolgt die Steuerung über eine Variable.

  $XML::Atom::ForceUnicode = 1;

Leider scheint XML::Feed keine Steuerung dafür zu haben. So daß man die Angaben nicht ohne weiteres an die Submodule weitergeben kann.
Wenn man aber genau weiss, welcher Typ der Feed hat und man auch sicher sein kann, das man nur Feeds von diesem Typ verwendet, kann man sich also die Nutzung des Wrappers XML::Feed ersparen und eines der beiden Module direkt nutzen; Dann kann man dort die UTF-8-Codierung entsprechend steuern.
In meinen Fall war dies jedoch keine Lösung, denn mein Skript soll beliebige Feeds verarbeiten können, unabhängig vom Typ.

Einziger Ausweg erscheint daher momentan nur das Setzen des Encodings für die Ausgaben:

binmode(STDOUT, ":utf8");

Dies hat den Effekt, daß bei dem Methodenaufruf auch unabhängig von den moduleigenen Steuerungen davon ausgegangen wird, daß der Objektinhalt in UTF8 codiert ist und somit dieser nicht nochmals darin umgewandelt wird.
Zufrieden bin ich damit nicht.

Hat jemand einen besseren Ansatz? Sieht man jetzt von einer Anpassung von XML::Feed ab…

Durch die weitere Nutzung der Seite stimmst du der Verwendung von Cookies zu. Weitere Informationen

Die Cookie-Einstellungen auf dieser Website sind auf "Cookies zulassen" eingestellt, um das beste Surferlebnis zu ermöglichen. Wenn du diese Website ohne Änderung der Cookie-Einstellungen verwendest oder auf "Akzeptieren" klickst, erklärst du sich damit einverstanden.

Schließen