Anzeige
Tutorialbeschreibung

PHP - Teil 40 - XML (Teil 5): RSS-Feeds einlesen und ausgeben

PHP - Teil 40 - XML (Teil 5): RSS-Feeds einlesen und ausgeben

Wie sich RSS-Feeds mittels PHP dynamisch generieren lassen, wurde bereits gezeigt. Ebenso interessant ist aber natürlich auch die andere Richtung: Wie also lassen sich RSS-Feeds mit PHP einlesen? Auch hierfür stellt die DOM-Erweiterung von PHP einige interessante Funktionen zur Verfügung. Welche das sind und wie die sich praktisch nutzen lassen, erfahrt Ihr in diesem Video.

Icon-Ersteller: Oxygen-Team

... übrigens findest du die komplette Serie hier: PHP-Workshop-DVD - Basics & Tricks - Schnapp sie dir in unserem Shop oder in der Kreativ-Flatrate!


RSS-Feeds werden auf unglaublich vielen Webseiten angeboten. Denkt beispielsweise an die RSS-Feeds von Heise, die es unter http://www.heise.de/news-extern/news.html gibt. Aber auch andere Webseiten stellen ihre Inhalte als RSS-Feeds bereit.

Bilder



 
Die per RSS-Feeds angebotenen Informationen können zunächst einmal natürlich in den eigenen Readern gelesen werden. Das ist allerdings nur eine Möglichkeit. Ebenso interessant ist es, die bereitgestellten RSS-Feeds einzulesen und mittels PHP in der eigenen Webseite auszugeben. Mit der DOM-Erweiterung von PHP ist das überhaupt kein Problem.

In diesem Tutorial wird mit einem einfachen RSS-Feed gearbeitet, der lokal vorliegt.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>medienwerke.de - Daniel Koch</title>
<description>CMS-Support, Bücher, Videotrainings ...</description>
<language>de</language>
<link>http://www.medienwerke.de/feed/</link>
<lastBuildDate>CEST02000000, 13 +02002011-10-20T14:50:23+02:0031 2011 11:29:07 +0000GMT</lastBuildDate>
<item>
<title>XML Schema: Die Nachteile von DTDs</title>
<description>XML Schema ist ein neuer Ansatz, um XML-Dokumenttypen ohne Einsatz einer 
DTD zu beschreiben. Dabei stellt sich zunächst die Frage, warum es eigentlich eines 
solch neuen Ansatzes bedarf. Denn schließlich wurde im vorherigen Kapitel gezeigt, 
dass sich Dokumenttypen durchaus mit DTDs definieren lassen. Es gibt also offensichtlich 
Defizite, die beim Einsatz von DTDs zu Tage [...]</description>
<link>http://www.medienwerke.de/2011/10/10/xml-schema-die-nachteile-von-dtds/</link>
<pubDate>Mon, 10 Oct 2011 18:27:12 +0000</pubDate>
<guid>http://www.medienwerke.de/?p=831</guid>
</item>
</channel>
</rss>


 
Es handelt sich hierbei um eine sehr einfache Datei, die aber dennoch alle wichtigen Elemente eines RSS-Feeds enthält.

Bilder



Die hier gezeigten Möglichkeiten lassen sich so aber auch auf alle anderen RSS-Feeds anwenden. So könnt ihr also auch Feeds von Drittanbietern einbinden, müsst dann eben nur auf die richtigen Pfadangaben achten. Eben diese Pfadangabe wird innerhalb einer Variablen hinterlegt.

$file = 'dateiname.xml';


 
Im nächsten Schritt wird ein neues DOM-Dokument erstellt. Innerhalb dieses Dokuments werden letztendlich die eingelesenen Daten des RSS-Feeds hinterlegt.

$xml = new DOMDocument('1.0', 'UTF-8');


DOMDocument werden zwei Parameter übergeben. Der erste Parameter gibt die Versionsnummer des Dokuments an, wie sie in der XML-Deklaration verwendet wird. Über den zweiten Parameter bestimmt man die anzuwendende Zeichenkodierung.

<?xml version="1.0" encoding="UTF-8"?>


Ein immer wieder auftauchendes Problem im Zusammenhang mit dem Einlesen von XML-Dateien stellen Leerzeichen und Zeilenumbrüche dar. Im ungünstigsten Fall werden diese nämlich als zusätzliche Textknoten betrachtet, was dann zu einer nicht kontrollierbaren Ausgabe führt. Um solche Probleme zu umgehen, gibt es die Eigenschaft preserveWhiteSpace. Darüber kann man explizit festlegen, ob die vorhandenen Leerzeichen und Zeilenumbrüche behalten werden sollen oder nicht. Will man sie behalten, setzt man den Wert der Eigenschaft auf TRUE, anderenfalls auf FALSE. Wird die Eigenschaft nicht gesetzt, greift automatisch der Standardwert TRUE. Im Zusammenhang mit RSS-Feeds sollte preserveWhiteSpace immer auf FALSE gesetzt werden.

$xml->preserveWhiteSpace = FALSE;
preserveWhiteSpace sollte immer vor dem Laden des Feeds definiert werden.


 
Wie effektiv dieses preserveWhiteSpace arbeitet, zeigt folgendes Beispiel.

<?php
$file = 'feed.xml';
$xml = new DOMDocument('1.0', 'UTF-8');
 $xml->preserveWhiteSpace = FALSE;
  $xml->load($file);
  $xml->save("ohneumbruch.xml");
?>


Hier wird das bereits bekannte XML-Dokument eingelesen. Aus dem eingelesenen Dokument werden nicht benötigte Leerzeichen und Zeilenumbrüche entfernt. Das so behandelte Dokument wird dann unter dem Namen ohneumbruch.xml abgespeichert. Vergleich man nun die originale mit der neu abgespeicherten Datei, werden die Unterschiede deutlich.

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>medienwerke.de - Daniel Koch</title>
    <description>CMS-Support, Bücher, Videotrainings ...</description>


 
Während im originalen Dokument alles schön übersichtlich wirkt, stellt sich das neu abgespeicherte Dokument deutlich „chaotischer“ dar.

<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"><channel><title>medienwerke.de - Daniel Koch</title><description>CMS-Support, Bücher, Videotrainings ...</description>


Diese Unübersichtlichkeit spielt bei dieser Datei allerdings keine Rolle, da dieses neu abgespeicherte Dokument ja ohnehin ausschließlich zur manuellen Weiterverarbeitung da ist.

Zurück zum Beispiel. Das Dokument, das innerhalb der Variablen $file deklariert wurde, muss nun geladen werden. Verwendet wird dafür die load()-Funktion.

$xml->load($file);


Achtet hier unbedingt darauf, dass tatsächlich load() verwendet wird. Denn DOM unterscheidet zwischen XML-Code, der in einem String hinterlegt ist, und XML-Code, der in einer Datei liegt. Bei der String-Variante muss loadXML() verwendet werden.

 
Noch ein allgemeiner Hinweis. Wenn ihr eure eigenen RSS-Feeds schreibt, liegt es in eurer Hand, diese fehlerfrei zu definieren. Dass RSS-Feeds bzw. die XML-Dateien tatsächlich fehlerfrei sind, ist bei fremden Feeds allerdings nicht garantiert. Und so kann es durchaus zu einer Fehlermeldung kommen, wenn man versucht, eine externe Feed-Datei zu laden.

Bilder



DOM erkennt also, ob es Fehler in der zu ladenden Datei gibt.

 
Die Hauptaufgabe ist jetzt bereits erfüllt - das externe Dokument wurde geladen und in ein DOM-Dokument überführt. Nun muss natürlich noch auf die Elemente des Feeds zugegriffen werden. Verwendet werden kann dafür getElementsByTagName().

$date = $xml->getElementsByTagName('title')->item(0)->nodeValue;


Darüber kann direkt auf ein Element über dessen Namen zugegriffen werden. Im gezeigten Beispiel handelt es sich dabei um das Element title. Welches Elements letztendlich ausgewählt werden soll, wird über item() bestimmt. Gibt man dort den Wert 0 an, wird im aktuellen Fall auf das erste title-Element zugegriffen, da die interne Zählung hier bei 0 beginnt. Nun soll allerdings nicht der Name des Elements, sondern dessen Inhalt ausgegeben werden. Der Zugriff auf eben jenen Inhalt geschieht dabei über nodeValue. Mehr ist tatsächlich nicht nötig, um auf die einzelnen Elemente und deren Inhalte zuzugreifen.

Bilder



 
Ein Problem gibt es nun allerdings noch: Die Anwendung ist momentan noch sehr statisch. So wird aktuell lediglich auf das erste item-Element zugegriffen. Was aber, wenn ein RSS-Feed – und das ist eher die Regel als die Ausnahme – aus sehr vielen Einträgen besteht? In solchen Fällen muss eine Schleife definiert werden, die alle Elemente durchläuft.


Die Ausgabe formatieren

Um wirklich alle item-Elemente und deren Inhalte anzusprechen, greift man zu einer foreach()-Schleife. Hier zunächst ein einfaches Beispiel, wie eine solche Schleife aufgebaut ist.

$item = $xml->getElementsByTagName('item');
foreach ($item as $elem) {
echo $elem->getElementsByTagName('title')
   ->item(0)
   ->nodeValue; 
}


Bei jedem Schleifendurchlauf wird das jeweilige item-Element angesprochen. Auf die einzelnen Elemente, die es innerhalb des item-Elements gibt, lässt sich dann über die bereits gezeigte Funktion getElementsByTagName() zugreifen.

 
Das folgende Beispiel zeigt, wie sich ein RSS-Feed einlesen und ausgeben lässt. Dabei erfolgt die Ausgabe innerhalb einzelner Tabellen.

<?php
$file = 'feed2.xml';
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->preserveWhiteSpace = FALSE;
$xml->load($file);
$item = $xml->getElementsByTagName('item');
foreach ($item as $elem) {
?>
  <table border="1">
     <tbody>
       <tr>
        <td><b>Titel:</b></td>
        <td><?php echo $elem->getElementsByTagName('title')
                            ->item(0)
                            ->nodeValue; ?></td>
      </tr>
       <tr>
         <td><b>Beschreibung:</b></td>
         <td><?php echo $elem->getElementsByTagName('description')
                            ->item(0)
                             ->nodeValue; ?></td>
        </tr>
        <tr>
          <td><b>Link:</b></td>
          <td><a href="<?php echo $elem->getElementsByTagName('link')
                             ->item(0)
                             ->nodeValue; ?>">Seite aufrufen</a></td>
         </tr>
         <tr>
            <td><b>Datum:</b></td>
            <td><?php echo $elem->getElementsByTagName('pubDate')
                              ->item(0)
                              ->nodeValue; ?></td>
          </tr>
       </tbody>
   </table>
   <br />
<?php
}
?>


 
Ruft man diese Seite im Browser auf, ergibt sich folgendes Bild:

Bilder



Wie ihr die Ausgabe letztendlich gestaltet, bleibt dann natürlich euch überlassen.



Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von franzg
  • 14.05.2017 - 02:51

Sehr gut erklärt, danke!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 07.10.2016 - 13:06

Danke tolles Video !

Portrait von dmtw2107
  • 16.11.2013 - 09:49

verständlich und toll erklärt danke für das tutorial

Portrait von InterMedia
  • 15.05.2012 - 15:59

Interessanter Beitrag zum auslesen von XML Informationen. Hat mir sehr geholfen um die Schnittstelle zwischen XML MySQL sauber hinzubekommen!

Portrait von leveler
  • 22.01.2012 - 13:09

Sehr gut! Wieder was dazugelernt.

x
×
×