Hallo,
ich hab keine wirkliche Detailahnung von PHP, will mich eigentlich auch nur zum Thema Syntax von RSS äußern.
$firstNode = $doc->getElementsByTagName("news");
Allerdings fällt mir hier auf, dass es in keiner Variante von RSS kein Element mit dem Tagname "news", also kein <news> gibt. Insofern kriegst Du hier nach den Regeln des DOM eine leere Liste zurück. Ich vermute, dass wirkt sich dann auf den weiteren Verlauf des Skriptes aus. Ich vermute aber nur; vielleicht entgeht mir hier irgendeine „Feinheit“ von PHP.
Dadurch ergibt sich aber leider folgende xml Datei:
Ausser dass – wie von Dir schon richtig beobachtet – die item-Elemente nicht Kindelemente des Channel-Elementes sind, gibt es ein paar weitere Fehler und mögliche Problemquellen und zu beachtende Idiotien in der Syntax von RSS. Ich erkläre das mal am besten anhand Deiner Ausgabe. Lass Dich nicht von meinen ausführlichen Anmerkungen erschrecken; ich verfolge leider die Geschichte der diversen RSS-Standards viel zu lange, mit entsprechenden Wissen. ;)
<?xml version="1.0" encoding="ISO-8859-1"?> <rss version="0.91">
Es gibt zwei in winzigen Details miteinander nicht kompatiblen Versionen von RSS, die sich beide RSS 0.91 nennen. Nein, das ist kein Scherz.
Die erste stammt von Netscape aus dem Juli 1999; die zweite stammt von einer privaten Firma namens Userland, die im Juni 2000 Netscapes Spezifikation genommen; ein paar Änderungen (wie z.B. einen eigenen Copyrighthinweis) gemacht hat und das auch als kompatibles RSS 0.91 beworben hat.
• Netscape RSS 0.91, Revision 3 • Userland RSS 0.91
Netscapes Variante hatte eine verpflichtende Deklaration eines Doctypes vorgesehen, die nach XML-Regeln dann zwischen XML-Deklaration und Root-Element eingefügt wird:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">
<rss version="0.91">
Du hast diesen Doctype nicht; das sieht dann nach Userlands RSS 0.91 aus. Allerdings: Wenn Du auf diesen Doctype verzichtest, kannst Du keine benannten Zeichen (Entities, so Dinger wie µ) in Deinem RSS nirgendwo einfügen, ausser den von XML erlaubten vier. Ein generischer XML-Prozessor (also fast jeder) kriegt dann ein Problem, stößt er auf so ein Entity. Du verwendest den Zeichensatz ISO 8859-1, bist also relativ limitiert in der Auswahl von nutzbaren Zeichen. Sobald Dein Newssystem Zeichen annimmt und ausspucken will, die nicht in diesem Zeichensatz enthalten sind – und das kommt schneller vor, hast Du ein Problem. PHP hat natürlich eine „Maskiere-komische-Zeichen“-Funktion, allerdings meine ich mich zu erinnern, dass diese HTML-Entities ausspuckt. Die dann hier die XML-Datei invalid machen.
Wahrscheinlich gibt es für Text-Content auch eine Funktion, die stattdessen Numerische Entities ausspuckt; wenn es eine solche gibst, solltest Du diese verwenden. Oder – aber das erfordert sicher größeres Wrestlen mit PHP – Du verwendest als Ausgabekodierung UTF-8.
<channel> <title>Cworx|org</title>
Soweit so klar. Du solltest nur beachten, dass Userlands RSS 0.91 eine maximale Begrenzung von 100 Zeichen als Textinhalt des title-Elementes auferlegt, Netscapes RSS 0.91 hat keine solche Begrenzungen. Ist aber ein sehr exotisches Thema. Gilt auch für alle title-Elemente im Feed.
<link>http://www.cworx.org</link>
Userlands RSS 0.91 hat hier eine maximale Länge von 500 Zeichen, das gilt für alle link-Elemente, egal wo sie vorkommen. Solltest Du unter längeren URIs leiden, wäre das vielleicht zu beachten. Netscapes RSS 0.91 hat keine solche Begrenzung.
<description>Beschreibung von Beispielwebsite</description>
Für alle description-Elemente in Feeds gibt es bei Userlands RSS 0.91 eine maximale Zeichenlänge von 500 Zeichen; bei Netscapes RSS 0.91 besteht keine solche Begrenzung.
<language>de-de</language>
Hier gibt es eine Verwirrung zwischen Netscape/Userland und dem W3C. Erstere schreiben Language Codes immer klein, letzteres übernimmt die Empfehlung der IETF, den Subcode nach ISO 3166 alpha-2 (hier das zweite „de“, das nicht für Deutsche Sprache sondern für Deutschland steht) groß zu schreiben, also als „de-DE“. Der RSS Parser, der darüber stolpert, muss aber wirklich von einem Spezifikation-Nazi geschrieben sein. Oder von einem „Asshole“ nach Pilgrim'schen Sprachgebrauch.
<copyright>cworxorg</copyright>
Nicht vergessen, solltest Du den Copyright-Hinweis ausbauen: Die maximale Zeichenlänge nach dem von Dir benutzten RSS 0.91 von Userland beträgt 100 Zeichen. Nicht gerade viel, wenn man Lizenzromane schreiben will.
<image> <url>http://www.cworx.org/images/get_firefox.gif</url> <title>cworxorg</title> <link>http://www.cworx.org</link> </image>
Ich vermute, das Firefox-Bild ist ein Platzhalter in der Testphase. Solltest Du da ein für Deine Seite aussagekräftigeres Bild einsetzen, beachte, dass Userlands RSS 0.91 Maxima von 144 Pixeln in der Breite und 400 Pixeln in der Höhe spezifiziert. Wieder gilt meine Aussage über Spezifikations-Nazis weiter oben, aber hey.
</channel>
Hier ist Dein eigentliches Problem, das übergehe ich mal. Nach all den korinthenkackerischen Anmerkungen weiter oben komme ich aber jetzt zu richtigen Fehlern:
<item> <id>1</id>
Kein einziger der vielen in XML geschriebenen Dialekte (meiner persönlichen Zählung nach sind es inzwischen zwölf), die sich alle RSS mit unterschiedlichen oder gleichen Versionsnummern nennt besitzt ein Element namens <id>. Keiner. Ab RSS 2.0 aufwärts gibt es aber <guid>, würdest Du auf RSS 2.0 wechseln könntest Du das verwenden. Allerdings würde ich Dir dann (aus technischen Gründen) eine global eindeutige ID für item-Elemente empfehlen, am besten eine URI.
<title>test</title> <author>2</author>
Weder Userlands RSS 0.91 noch Netscapes RSS 0.91 besitzen ein Element namens <author>. Es gibt <managingEditor> und <webMaster>, beides sind aber nur Kindelemente des channel-Elementes, dürfen also nicht als Kindelemente von item-Elementen auftauchen. Ausserdem ist ihr einziger erlaubter Inhalt eine Mail-Adresse; in Zeiten von Spam ist das nicht gerade toll.
<description>test</description>
Die übliche Warnung: RSS 0.91 darf hier nur Text enthalten, kein HTML. Auch kein maskiertes; das sollte dann nämlich eigentlich als Text interpretiert werden. Ab RSS 2.0 wird als Inhaltsmodell allerdings HTML angenommen. Allerdings nur für description-Elemente, nicht für title- oder andere inhaltstragende Elemente.
<link>http://www.cworx.org/index.php</link> <date>1146776568</date>
Kein einziger RSS-Dialekt besitzt ein Element namens date.
RSS 0.91 (beide Varianten) erlauben als Kindelemente des channel-Elementes das Element <pubDate> (in genau dieser Groß- und Kleinschreibung), aber nicht als Kindelemente der item-Elemente.
RSS 2.0 erlaubt pubDate-Elemente auch als Kindelemente von item-Elementen.
In keinem einziges RSS-Dialekt wird das Datums als Timestamp angebenen. In Netscapes RSS 0.91 gibt es zwar keine explizite Einschränkung, allerdings wird aus den Beispielen klar, dass eine Datumsangabe nach RFC 822 genutzt wird. In Userlands RSS 0.91 wird dies explizit gefordert. Das sähe dann ungefähr so aus:
[code lang=mail-header]Thu, 04 May 2006 21:02:48 GMT[/code]
Das ist das klassisches Format wie Zeitpunkte in Mails angegeben werden; PHP sollte da Funktionen für bieten. Es wurden da auch kleinere Problemchen mit diesen etwas antiquirten Zeitformat berichtet, z.B. mit der anscheinend eigentlich erlaubten Verkürzung des Jahres auf nur zwei Stellen und der Angabe von Zeitzonen in komischen militärischen Kürzeln aber in der Praxis dürfte esda keine Probleme geben.
...
Du merkst: Das Thema RSS eignet sich gar wunderbar für Korinthenkackerei auf fitzeligem Detailniveau. Wenn man einen RSS-Feed anbietet, empfiehlt es sich immer, das Resultat im Feedvalidator zu testen; dieser „Validator“ ist derzeit der beste, den ich kenne. Schon allein weil er von noch mehr auf Details fixierten Leutchen gebastelt wird, als ich es bin.
Zwei weitere Tips hätte ich noch für Dich:
Zum einen: Nutze eine auf die Erstellung von Feeds spezialisierte Software, anstatt selber im XML rumzuwurschteln. Die Spezifikationen von RSS haben diverse Lücken, Fehler und Gedankenlosigkeiten; es ist immer besser ein Produkt zu nehmen, dessen Autor sich (möglichst fanatisch) darum kümmert, anstatt es selber zu versuchen.
Zum anderen: Nutz nicht RSS 0.91, Gründe dafür habe ich ja schon oben geliefert.
Noch besser, nutz gar kein RSS, nutze lieber Atom 1.0 (Kompletter Standard). Atom ist ein richtiger Standard, abgesegnet von einer richtigen Standardsorganisation, nicht nur ein locker flockig dahingetippter Text wie es die meisten RSS-Dialekte sind. Ich will sagen: Atom wurde von Leuten entwickelt, die sich kümmern, auch um exotische Detailfälle und nicht so exotischere. Viele der Probleme, die RSS aufgrund der Vagheit der jeweiligen Spezifikationen hat, sind in Atom gelöst. Man hat nur Vorteile dadurch; inzwischen ist die Unterstützung von Atom 1.0 in den großen Feedreadern auch ziemlich komplett. Auch bei großen Firmen wie Microsoft; zumindest höre ich das andauernd über den IE 7 und Vista.
Wenn Du aus was für Gründen an dem Akronym „RSS“ hängst, schmeiss es trotzdem weg und verwende Atom und die Bezeichnung „Feed“. Die Leute sollten sich nicht um technische Details kümmern müssen.
Und wenn Du trotzdem RSS benutzen willst – mir fällt kein überzeugender Grund dafür ein – dann nimm RSS 2.0. Das leidet nicht unter komischen, aus heutiger Sicht nicht nachvollziehbaren Limitationen wie die beiden RSS 0.91 Dialekte. Allerdings gibt es natürlich auch dort ein paar Vagheiten, die Du berücksichtigen solltest.
Für so etwas gibt es neuerdings (seit klar wurde, dass es nie mehr eine neue Revision von RSS 2.0 geben wird) die Praxis, Best Practice Dokumente oder Profile von RSS zu entwickeln, die man als Veröffentlicher von RSS 2.0 Feeds beachten sollte. Das „halb offizielle“ RSS Board versucht derzeit ein relativ komplettes Profil zu entwerfen. Auch wenn sich das noch in der Entwicklung befindet, solltest Du das beachten. Weniger toll finde ich Dabe Winers „A busy developers guide to RSS 2.0“, aber eventuell solltest Du es auch zumindest mal lesen. Dave Winer (als ehemaliger CEO von Userland) hat auch über die Jahre verteilt in seinen unterschiedlichen Blogs (und in den Kommentarsektionen anderer Blogs) Kommentare abgegeben, wie RSS seiner Ansicht nach zu benutzen sei, zum Beispiel „Guids are not just for geeks anymore“. Wenn man letztendlich RSS 2.0 so basteln will, wie es der Autor der RSS 2.0 Spezifikation vorsieht, sollte man diese eigentlich beachten. Muss man aber gottseidank nicht.
Tim