UTF-8 Codierung in RSS-Feed stimmt nicht ganz

andy72

Erfahrenes Mitglied
Hi@all,

Habe folgendes Problem:
In einer PHP-Seite rufe ich verschiedene RSS-Feeds ab, teils sind diese UTF-8 codiert,
Teils aber Plain Text. Folgendes Script sollte mir helfen, herauszufinden, ob der Text des Feeds in UTF-8 ist, wenn ja, soll das Script den UTF-8 Text in ISO-8859-1 umwandeln.
Das Problem: die Funktion "sieht" das UTF-8, codiert es auch um in benanntes ISO, jedoch kommt der Rest Text, der nicht verändert werden soll plötzlich ohne Umlaute *kopfkratz*.

Hier der Quelltext:
Code:
 $enc = mb_detect_encoding($text, "UTF-8");
  if( $enc === "UTF-8" )
    $text = utf8_decode($text);
 
  return trim($text);

Der HTML-Header ist übrigens schon auf Charset ISO-8859-1...

Danke Euch für die Hilfe :)
Andy
 
Eigentlich sollten die RSS-Feeds ihre Zeichenkodierung explizit im „Content-Type“-Header-Feld angeben, so dass du dich auf diese Information beschränken kannst. Wie rufst du die denn ab?
 
habe das ganze nur von woanders kopiert:
Code:
function RSStoArray($feed) {
	$content = file_get_contents ($feed);	
	$items = explode ('<item', $content);
	array_shift($items);
	$i = 0;
	
	foreach ($items as $item) {
		$array[$i]['title']			= getTextBetweenTags($item, 'title');
		$array[$i]['link']			= getTextBetweenTags($item, 'link');
		$array[$i]['description']	= getTextBetweenTags($item, 'description');
		$array[$i]['author'] 		= getTextBetweenTags($item, 'author');
		$array[$i]['category'] 		= getTextBetweenTags($item, 'category');
		$array[$i]['comments'] 		= getTextBetweenTags($item, 'comments');
		$array[$i]['enclosure'] 	= getTextBetweenTags($item, 'enclosure');
		$array[$i]['guid'] 			= getTextBetweenTags($item, 'guid');
		$array[$i]['pubDate'] 		= getTextBetweenTags($item, 'pubDate');
		$array[$i]['source'] 		= getTextBetweenTags($item, 'source');
		$i++;
	}
	
	return $array;
}

function getTextBetweenTags($text, $tag) {
	$StartTag = "<$tag";
	$EndTag	= "</$tag";
	
	$StartPosTemp = strpos($text, $StartTag);
	$StartPos = strpos($text, '>', $StartPosTemp);
	$StartPos = $StartPos + 1;
	
	$EndPos = strpos($text, $EndTag);
	
	if($EndPos > $BeginPos)	{
		$text	= substr ($text, $StartPos, ($EndPos - $StartPos));
	} else {
		$text = '';
	}
	
	$text = str_replace('<![CDATA[', '', $text);
	$text = str_replace(']]>', '', $text);

  $enc = mb_detect_encoding($text, "UTF-8");
  if( $enc === "UTF-8" )
    $retval = utf8_decode($text);
  else
    $retval = $text;  
	return trim($retval);
}

Irgendwie hab ich keinen Plan, wie ich an die daten noch dran komme, da ja in der ersten Funktion schon alles zerhäggselt wird (explode) :D

LG
Andy
 
Ich würde die Daten mit der fsockopen()-Funktion abholen und anschließend die gesuchten Teile mit einem XML-Parser herausholen.

Die fsockopen()-Funktion hat den Vorteil, dass du auch den Header der Antwort bekommst, in dem unter anderem die verwendete Zeichenkodierung steht (stehen sollte). Steht sie dort nicht und auch nicht im „encoding“-Attribut der XML-Deklaration, kann es sich laut XML-Spezifikation nur noch um die Unicode-Kodierung UTF-8 oder UTF-16 handeln. Bei UTF-16 muss dann jedoch eine BOM vorhanden sein. Siehe dazu auch Automatische Erkennung von Zeichenkodierungen.
 
Hehe,

das klingt cool, ich werd das heute abend mal testen, melde mich denn, ob es funktioniert hat - in diesem Sinne erstmal Danke :)

LG
Andy
 
Hi nochmal,

habe im Inet was gefunden, das ich mit xml-funktionen alles aus- und umsortieren kann.
Allerdings habe ich bemerkt, dass die ganze Sache mit xml-funktionen und fsockopen()
ganz schön unter der Performance leidet - ist das normal ? (Ich benutze noch PHP4)

LG
Andy
 
Die fsockopen()-Funktion sollte nicht langsamer sein als vergleichbare Funktionen. Was die eigene XML-Funktion angeht, kann es aber durchaus sein, dass PHP bereits Funktionen anbietet, die dasselbe leisten aber schneller arbeiten.
 
Hm,
ich nutze ja PHP-eigene Funktionen zur Bearbeitung von XML;)
Ich Poste den Code heute abend mal, bin noch auf Arbeit :D

LG
Andy
 
Sooo, nun der Code:

Code:
function XMLOpen($url) {
  $toOpen   = parse_url($url);
  $request  = "GET ".$toOpen['scheme']."://".$toOpen['host'].$toOpen['path'];
  if( count($toOpen['query']) > 0 )
    $request .= "?".$toOpen['query'];
  $request .= " HTTP/1.1\r\nHost: ".$toOpen['host']."\r\n\r\n";
  
  $fp = fsockopen ($toOpen['host'], 80, $errno, $errstr, 30);
  if (!$fp) {
    return NULL;
  }
  else {
    fputs ($fp, $request);
    $xml = NULL;
    while (!feof($fp)) {
       $xml .= fgets($fp,128);
    }
    fclose($fp);
    $xml = substr($xml, strpos($xml, "<"), strlen($xml));
    $xml = trim($xml);
    return $xml;
  }
}

$insideitem = false; 
$tag = ""; 
$title = ""; 
$description = ""; 
$link = "";

function startElement($parser, $tagName, $attrs) {
  global $insideitem, $tag; 
   if ($insideitem) {
     $tag = $tagName;
   } 
   else
   if ($tagName == "ITEM") { 
     $insideitem = true; 
   }
}

function characterData($parser, $data) { 
  global $insideitem, $tag, $title, $description, $link;
  if ($insideitem) {
    switch ($tag) { 
       case "TITLE": 
       $title .= $data; 
       break; 
       case "DESCRIPTION": 
       $description .= $data; 
       break; 
       case "LINK": 
       $link .= $data; 
       break; 
    } 
  }
}

function endElement($parser, $tagName) {
  global $insideitem, $tag, $title, $description, $link; 
  if ($tagName == "ITEM") { 
    printf("<p class=\"newsItem\"><a href='%s'>%s</a>\n", trim($link),utf8_encode(trim($title))); 
    printf("%s</p>\n",trim(utf8_encode($description)));
    $title = ""; 
    $description = ""; 
    $link = "";
    $insideitem = false;
  }
}


function readRSS($url) {
  $xml = XMLOpen($url);
  $parser = xml_parser_create("ISO-8859-1");
  xml_set_element_handler($parser, "startElement", "endElement");
  xml_set_character_data_handler($parser, "characterData"); 
  xml_parse($parser, $xml);
  xml_parser_free($parser);
}

readRSS("http://www.cinema.de/feeds/cin_rss_main.xml");

Die Quelle stammt von:
http://www.sitepoint.com/article/php-xml-parsing-rss-1-0/4

LG
Andy
 
Problem ist behoben:

der Server hat auf ein Connection-Close gewartet, da ich das im Header nicht angegeben habe :D Läuft jetzt super - Danke nochmal :)

Andy
 
Zurück