kungschu: Einträge aus DB in XML-File einfügen

Hallo.

Wie kann ich meinen Blog (Beiträge liegen in einer DB) auch in einer XML-File ausgeben; sprich: wie gebe ich den Inhalt einer DB in einer XML-File aus?

Ich konnten kein Tutorial oder dergleichen zu genau diesem Thema finden. Es fehlen mir also die treffenden Stichworte bzw. Quellen.

Wo finde ich Beispiele und Erklärungen?

Herzlichen Dank für alle Tips!

MfG, Kungschu.

  1. Hallo kungschu,

    Du musst Dir erst Gedanken darueber machen, wie deine XML-Struktur aussehen soll. Soll sie irgendeinem Standard gerecht werden wie zb. RSS oder brauchst du die Daten in einem anderen Zusammenhang.

    Wenn Du das herausgedunden hast, baust du dir eine kleine Beispieldatei als Referenz, bzw. besorgst dir eine in dem gewuenschten Standard.

    Dann liest du die DB aus, baust die ganze Datei als String zusammen, also in etwa so, wie du auch HTML produzieren wuerdest, speicherst das Ergebnis und fertig.

    Gruß,

    Dieter

    1. Hallo.

      Du musst Dir erst Gedanken darueber machen, wie deine XML-Struktur aussehen soll. Soll sie irgendeinem Standard gerecht werden wie zb. RSS oder brauchst du die Daten in einem anderen Zusammenhang.

      Ich möchte RSS- und/oder AtomFeed ermöglichen.

      Wenn Du das herausgedunden hast, baust du dir eine kleine Beispieldatei als Referenz, bzw. besorgst dir eine in dem gewuenschten Standard.

      Nehmen wir zum Beispiel RSS:

        
      <?xml version="1.0" encoding="utf-8"?>  
      <rss version="2.0">  
        
      <channel>  
        
      <title>Blog</title>  
      <description>Ein Blog</description>  
      <link>http://example.org</link>  
        
      <item>  
      <title>Titel</title>  
      <description>Zusammenfassung</description>  
      <link>Link zu Artikel</link>  
      <author>Autor</author>  
      <guid>Die ID</guid>  
      </item>  
        
      </channel>  
      </rss>  
      
      

      Dann liest du die DB aus, baust die ganze Datei als String zusammen, also in etwa so, wie du auch HTML produzieren wuerdest, speicherst das Ergebnis und fertig.

      Das kann ich so nun nicht ganz nachvollziehen.
      Ich starte also einen Query und hole mir die Einträge aus der Datenbank. Ich baue mit einer foreach-Schleife für jeden DB-Eintrag einen xml-item, packe diesen in einen string und speichere das Ergebnis.
      Wie meinst du das "speicherst das Ergebnis und fertig"?

      MfG, Kungschu.

      1. Hallo kungschu,

        Das kann ich so nun nicht ganz nachvollziehen.
        Ich starte also einen Query und hole mir die Einträge aus der Datenbank. Ich baue mit einer foreach-Schleife für jeden DB-Eintrag einen xml-item, packe diesen in einen string und speichere das Ergebnis.

        Genau so

        Wie meinst du das "speicherst das Ergebnis und fertig"?

        Du kannst genausogut natuerlich deine php-Datei mit entsprechendem Content-Type direkt als XML auslieferen. Wenn es um RSS geht, ist das ausreichend. In deinem Ausgangsposting war halt die Rede von einem File. In diesem Fall muesstest du den XML-String mit file_put_contents() oder fwrite() in einer Datei speichern.

        Gruß,

        Dieter

        1. Hallo Dieter.

          Du kannst genausogut natuerlich deine php-Datei mit entsprechendem Content-Type direkt als XML auslieferen. Wenn es um RSS geht, ist das ausreichend.

          Heißt das, wenn ich nur RSS-Feed anbieten möchte, kann ich etwa eine File rss.php anbieten und habe lediglich darauf zu achten, den ausgegebenen Inhalt XML/RSS konform auszuzeichen.?(Ich könnte also die DB-Abfrage direkt in der gleichen File ausführen)

          Die (XML-fähigen-) Browser spielen da mit?

          In deinem Ausgangsposting war halt die Rede von einem File. In diesem Fall muesstest du den XML-String mit file_put_contents() oder fwrite() in einer Datei speichern.

          Alternativ erzeuge ich also nach jedem neuen Eintrag eine neue rss.xml File.? (Und lösche die Alte)

          Herzlichen Dank für deine Hilfe!

          MfG, Kungschu.

          1. Hallo kungschu,

            Heißt das, wenn ich nur RSS-Feed anbieten möchte, kann ich etwa eine File rss.php anbieten[...]

            Ja, vorausgesetzt, dein Content-Type und dein Characterset stimmen. Vor der Ausgabe muesste demanch
            header('Content-type: text/xml; charset=utf-8');
            stehen (ich habe das nicht ueberprueft).

            Die (XML-fähigen-) Browser spielen da mit?

            Ja, weil das bei denen ankommt, _ist_ XML.

            In deinem Ausgangsposting war halt die Rede von einem File. In diesem Fall muesstest du den XML-String mit file_put_contents() oder fwrite() in einer Datei speichern.
            Alternativ erzeuge ich also nach jedem neuen Eintrag eine neue rss.xml File.? (Und lösche die Alte)

            Ja, die gaengigen PHP-Funktionen zum Erzeugen von Dateien haben ja auch immer Parameter zu Loeschen alten Datei.

            Gruß,

            Dieter

            1. Hallo.

              Ok, dann vorerst nochmals Danke für deine Hilfe. Ich werde sehen, ob ich heute noch eine ersten Versuch fertigstellen kann. Im Moment tendiere ich dazu, immer ein neues XML-Dokument zu erstellen.

              Gegebenenfalls wende ich mich dann nochmals an dich.

              MfG, Kungschu.

              1. Hallo kungschu,

                Im Moment tendiere ich dazu, immer ein neues XML-Dokument zu erstellen.[...]
                Gegebenenfalls wende ich mich dann nochmals an dich.

                Klar, kein Problem. Persoenlich wuerde ich mehr zu der 'On-the-fly'-Loesung tendieren. Ich kann dir aber auf Anhieb kein vernuenftiges Argument nennen, das ist mehr so ein Gefuehl.

                Gruß,

                Dieter

                1. Hallo Dieter.

                  Nun habe ich es versucht und zumindest ein halbes Ergebnis erzielt: Die XML-File wird erstellt bzw. ersetzt, wenn sie schon existiert, und ist soweit "lesbar". (Sie ist noch nicht valide; damit befasse ich mich erst später)

                  Trotzdessen erhalte ich einen Fehler. (Vermutlich, weil ich mit meinem Array etwas falsche mache.)

                  Der (relevante) Code zur Erstellung der <item>s:

                    
                  while($row = mysql_fetch_assoc($result)) {  
                    
                  $xml_content[]="<item> <title>".$row['head']."</title> <description>".$row['description']."</description> <link></link> <author>kungschu</author> <guid>".$row['id']."</guid> </item>";  
                    
                  }  
                    
                  $xml = implode("\\n", $xml_content);  
                    
                  $new_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<rss version=\"2.0\">\n\n<channel>\n\n<title>Blog</title>\n<description>Ein Blog</description>\n<link>http://example.org</link>\n\n".$xml."\n\n</rss></channel>";  
                  
                  

                  Die Fehlermeldung lautet: (line 59 ist die Zeile "$xml_content[]=...")
                  "Notice: Undefined index: id in [Pfad zu meiner php-File] on line 59"

                  Was kannst du an meinem Code kritisieren? Was sollte, deiner Meinung nach, verbessert werden? Sollte ich etwa [$i] schreiben und $i permanent hochzählen ($i++;)?

                  Um eine valide XML/RSS-File zu erhalten, muss ich ja, unter anderem, <guid> definieren. Nun frage ich mich, wie ich einen (einmaligen) Link angeben kann, wo mein Blog nur aus Full Posts besteht, sprich, kein Artikel eine "eigene File" bekommt?

                  Vorerst soweit. Ich danke dir..

                  MfG, Kungschu.

                  1. Hallo.

                    Zusatz:

                    Nun habe ich festgestellt, dass der Fehler nicht auf den Array zurück zu führen ist, sondern verursacht wurde, weil ich "id" mit dem Query garnicht abgefragt hatte. Ein Flüchtigkeitsfehler.. Deine Meinung zu dem Code und der anderen Frage (<guid>) interessiert mich natürlich nach wie vor.

                    Zudem habe ich den Code (der Lesbarkeit wegen) nochmals "formatiert" und den Array nummeriert:

                      
                    while($row = mysql_fetch_assoc($result)) {  
                      
                    $xml_content[$i] = "<item>";  
                    $xml_content[$i] .= "<title>".$row['head']."</title>\n";  
                    $xml_content[$i] .= "<description>".$row['message']."</description>\n";  
                    $xml_content[$i] .= "<link></link>\n";  
                    $xml_content[$i] .= "<author>kungschu</author>\n";  
                    $xml_content[$i] .= "<guid>".$row['id']."</guid>\n";  
                    $xml_content[$i] .= "</item>\n";  
                      
                    $i++;  
                      
                    }  
                      
                    $xml = implode("\\n", $xml_content);  
                      
                    $new_xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";  
                    $new_xml .= "<rss version=\"2.0\">\n\n";  
                    $new_xml .= "<channel>\n\n";  
                    $new_xml .= "<title>Blog</title>\n";  
                    $new_xml .= "<description>Ein Blog</description>\n";  
                    $new_xml .= "<link>http://example.org</link>\n\n";  
                    $new_xml .= $xml;  
                    $new_xml .= "</rss>";  
                    $new_xml .= "</channel>";  
                    
                    

                    MfG, Kungschu.

                    1. Hallo kungschu,

                      Meiner Meinung nach machst du das etwas zu kompliziert. Ich wuerde mir den ganzen Array sparen und die Daten als String bearbeiten.

                        
                      // ich bin ein Einfach-Anfuhrungszeichen-Fetichist, deshalb stuende in meiner Konfigurationsdatei:  
                      define('NL', "\n"); // evtl. if(!defined('NL')) { define('NL', "\n"); }  
                        
                      $xml = '<?xml version="1.0" encoding="utf-8"?>' . NL  
                          .= '  <rss version="2.0">' . NL  
                          .= '  <channel>' . NL  
                          .= '  <title>Blog</title>' . NL  
                          .= '  <description>Ein Blog</description>' . NL  
                          .= '  <link>http://example.org</link>' . NL . NL;  
                        
                      while($row = mysql_fetch_assoc($result)) {  
                        $xml .= '  <item>' . NL  
                             .= '    <title>' . strip_slashes($row['head']) . '</title>' . NL  
                             .= '    <description>' . strip_slashes($row['message']) . '</description>' . NL  
                             .= '    <link></link>' . NL  
                             .= '    <author>kungschu</author>' . NL  
                             .= '    <guid>' . strip_slashes($row['id']) . '</guid>' . NL  
                             .= '  </item>' . NL . NL;  
                        $i++;  
                      }  
                        
                      $xml .= '  </rss>' . NL  
                           .= '  </channel>' . NL;  
                      
                      

                      Das ist einfach, hat ein nettes Syntaxhighlighting und man kann sich den ganzen Kram mit " usw. sparen.
                      Schneller soll es auch sein, aber erst ab einer Milliarde Eintraege ;-)

                      Gruß,

                      Dieter

                      1. Hallo Dieter.

                        Meiner Meinung nach machst du das etwas zu kompliziert. Ich wuerde mir den ganzen Array sparen und die Daten als String bearbeiten.

                        Das mag sein. Es ist das erste Mal, das ich derartiges zu realisieren versuche. Es ist eine "learning by doing Aufgabe", die ich mir selbst "auferlegt" habe. In der Tat, dein Code ist die bessere Lösung. define kannte ich zudem noch garnicht.. Sehr praktisch.

                        Mir viel auf, dass in der while-Schleife nach wie vor $i++; steht; den Nutzen kann ich nun aber nicht mehr nachvollziehen. Ist das von dir "vergessen" worden?

                        Um nochmals auf <guid> zurück zu kommen: Wie könnte ich das lösen? Der Blog wird ja nur aus einer Seite bestehen, auf der alle Posts nach Aktualität nacheinander ausgegeben werden. <guid> ist für eine valide XML-File leider vorgeschrieben. (Oder täusche ich mich da?)

                        Genügt es, als <guid> die ohnehin für jeden Eintrag per auto_increment erzeugte id zu verwenden?

                        MfG, Kungschu.

                        1. Hallo,

                          Um nochmals auf <guid> zurück zu kommen: Wie könnte ich das lösen? Der Blog wird ja nur aus einer Seite bestehen, auf der alle Posts nach Aktualität nacheinander ausgegeben werden. <guid> ist für eine valide XML-File leider vorgeschrieben. (Oder täusche ich mich da?)

                          Für XML ist es nicht vorgeschrieben, weil XML so etwas nicht vorschreiben kann. Für RSS 2.0 auch nicht, es empfiehlt sich aber sehr. In Atom ist man aus schlechten Erfahrungen mit RSS klug geworden und schreibt eine <id> vor.

                          Genügt es, als <guid> die ohnehin für jeden Eintrag per auto_increment erzeugte id zu verwenden?

                          Im Prinzip kann man laut „RSS Spezifikation“ in <guid> reinschreiben, was man will. Sollte man aber nicht. Man sollte schon der Definition von GUID folgen, die da lautet „Global unique identifier“, d.h. etwas, das global, universell eindeutig und einzigartig ist. Warum?

                          Software, die Feeds liest, nimmt diese Dinger zum Identifizieren von einzelnen Einträgen. Bei vielen Feeds (Think: Google Reader) kommt es dann zu Doppelungen, ein Eintrag ist nicht mehr eindeutig identifiziert, d.h. man muss Krempel erfinden, um den Eintrag am Inhalt zu identifizieren. Und dann verbessert der Autor einen Tippfehler im Eintrag und das wird im Feed neu gepostet. Eigentlich ist der Eintrag logisch gesehen derselbe wie noch fünf Minuten vorher, aber der Inhalt hat sich verändert. Die GUID dient also dazu zu sagen, dass ein Eintrag in einem Feed derselbe ist. Autoren von Feedreadern finden so etwas sehr wichtig, weil es ihnen das Leben sehr viel einfacher macht. Wenn das jetzt zu schnell war: Ich hab vor längerem mal einen lngeren Beitrag geschrieben, der das Anhand eines Beispieles verdeutlicht.

                          Was nimmst Du jetzt als GUID? Was ist global eindeutig und einzigartig? Ein Vorschlag ist die URL des Beitrages, d.h. etwas wie http://example.org/blog/eintrag-1. Oder http://example.org/blog.php#eintrag-1 Hauptsache es ist eindeutig und ändert sich im Verlaufe der Zeit nicht.

                          Wenn Du kein Archiv der Einträge und demzufolge keine Permalinks hast, dann wird es etwas komplizierter. Wenn Du dann nicht darauf achten willst, dass Du GUIDs doppelt vergibst, dann nimm Tag URIs. Das sind keine richtigen HTTP-URLs, aber dennoch Bezeichner nach einem definiertem Schema, die zusätzlich den Vorteil haben, dass das Datum da hinein kodiert ist. Aber das driftet schon leicht in die esoterische Ecke ab.

                          Ansonsten noch drei Tips:
                          • Ich würde das RSS oder Atom entweder per Template oder per spezialisiertem Feed-Modul zusammenbauen. Das ist bequemer und weniger fehleranfälliger als das String-Zusammenfügen.
                          • Nicht vergessen, jede Änderung an der Programmlogik des Feeds solltest Du mit dem FeedValidator überprüfen und dessen Ratschläge befolgen.
                          • (Nicht ganz so wichtig: Ich würde Atom nehmen, es ist etwas striker definiert als RSS und insofern hat man da weniger Zweideutigkeiten und evtl. eine etwas bessere Unterstützung in anderer Software. Aber RSS geht auch.)

                          Tim

                          1. Hallo Tim.

                            Vielen Dank für deinen Beitrag und, vorallem, für den Verweis auf das sehr umfangreiche ältere Posting.
                            Leider habe ich die nächsten Tage kaum Zeit, werde mich also wohl erst mitte nächster Woche wieder intensiver mit meinem Script, der Erzeugung des Feeds und somit deinem Posting beschäftigen können.
                            Evtl. versuche ich doch noch, eine Lösung mit Permalinks zu schaffen. Mit Templates habe ich noch nie gearbeitet.

                            MfG, Kungschu.

                        2. Hallo kungschu,

                          Da $i++ ist natuerlich Unfug, das habe ich einfach uebersehen. Ansonsten hat Tim ja schon alles gesagt.

                          Gruß,

                          Dieter

  2. Hallo kungschu,

    Wie kann ich meinen Blog (Beiträge liegen in einer DB) auch in einer XML-File ausgeben; sprich: wie gebe ich den Inhalt einer DB in einer XML-File aus?

    nimm z.B. MS SQL-Server, der kann das von Haus aus :-)

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz.

      Ich habe keinen eigenen Server. Zudem möchte ich "von Haus aus" vermeiden und das Ganze selbst realisieren.

      Danke dir.

      MfG, Kungschu.