Zugriff auf die neuesten Beiträge / Einbindung in eigene Seiten



  • Hallo,

    immer wieder kommt der Wunsch auf, die aktuellen Beiträge in anderen Seiten einzubinden oder einen ActiveDesktop etc. für das Forum zu bekommen.

    Ich habe eine Funktion realisiert, die halbstündlich aktualisiert eine XML-Datei mit einer Übersicht aller Threads (ohne Neuigkeiten, OT) generiert.

    Die Datei ist ladbar unter

    http://www.c-plusplus.net/php/xmlnews/cpp-de.xml

    Wobei beim Download in einem Browser die XML sofort via XSL nach HTML transformiert wird (beim IE - nicht in Opera, NS).

    Ansonsten sieht die XML ungefähr so aus:

    <?xml version="1.0"  encoding="ISO-8859-1"?> 
    <?xml-stylesheet type="text/xsl" href="http://www.c-plusplus.net/php/xmlnews/cpp_channels_genhtml.xsl"?> 
    
    <topics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.c-plusplus.net/php/xmlnews/cpp_channels.xsd"> 
     <header> 
      <channel>C/C++-Forum global</channel> 
      <copyrightowner>www.c-plusplus.net</copyrightowner> 
      <language>de</language> 
      <update_mins>30</update_mins>
      <timestamp>1058621537</timestamp> 
      <date>19.07.2003</date> 
      <time>15:32</time> 
      <comment>Dies ist der allgemeine Newschannel für alle technischen Themen des Boards.</comment> 
     </header> 
     <topic> 
      <title>Mehrsprachige Programme erstellen</title> 
      <link>http://www.c-plusplus.net/forum/topic,42925.html</link> 
      <timestamp>1058621481</timestamp> 
      <date>19.07.2003</date> 
      <time>15:31</time> 
      <poster>Alexander Sulfrian</poster> 
      <forum>Borland C++ Builder (VCL/CLX)</forum> 
      <forum_link>http://www.c-plusplus.net/forum/forum,2.html</forum_link> 
      <cat>Entwicklungssysteme</cat> 
      <cat_link>http://www.c-plusplus.net/forum/index.php?c=1</cat_link> 
     </topic> 
     <topic> 
    ... 
     </topic> 
    </topics>
    

    Der Aufbau der Datei ist als XML-Schema beschrieben und befindet sich unter:
    http://www.c-plusplus.net/php/xmlnews/cpp_channels.xsd

    Damit werden folgenden Anwendungen möglich:
    😉 "Poller", Tool das regelmäßig die XML-Datei abfragt und in einer Applikation darstellt - kann z.B. ein Java- oder C++-Client sein.
    😉 Active-Desktop-Hintergrund, dazu muß aber eine schönere XSL-Transformation geschrieben werden mit "bunterem" HTML
    😉 andere Seiten können die letzten 5 bis 10 aktiven Threads anzeigen, indem über ein PHP-Script die XML geladen und geparst wird

    Und das alles ohne zusätzliche Last für die Datenbank - es sind nur 2 Abfragen pro Stunde, ansonsten wird einfach nur immer die XML vom Server abgerufen. Und falls jemand nämlich das HTML vom Forum parsen will ist das natürlich viel schwieriger, wenn das Layout ein wenig geändert wird.



  • Hier gibt's nun gleich einen PHP-Client, der die Datei lädt und eine Seite daraus formatiert:

    Demo: http://www.c-plusplus.net/php/xmlnews/news_demo.php

    Der Parser verwendet die SAX-API. Hier der Quellcode:

    <?php 
    /* 
      Demo zum einlesen des XML-Newschannel nach php 
      verwendet SAX als XML-Parser 
      Marcus B&auml;ckmann    ;) 
      www.c-plusplus.net 
    */ 
    
    $file = "http://www.c-plusplus.net/php/xmlnews/cpp-de.xml"; 
    
    $numberofa = 0; 
    $maxa = 10; // Anzahl gezeigter Artikel 
    
    $inside_header = "false"; 
    
    $topic_title = ""; 
    $topic_link = ""; 
    $topic_timestamp = ""; 
    $topic_date = ""; 
    $topic_time = ""; 
    $topic_poster = ""; 
    $topic_forum = ""; 
    $topic_forum_link = ""; 
    $topic_cat = ""; 
    $topic_cat_link = ""; 
    
    $header_channel = ""; 
    $header_copyrightowner = ""; 
    $header_update_mins = ""; 
    $header_language = ""; 
    $header_timestamp = ""; 
    $header_date = ""; 
    $header_time = ""; 
    $header_comment = ""; 
    
    $last_pcdata = ""; 
    
    function pageHeader() 
    { 
       print("<html><head/><body>"); 
    } 
    
    function pageFooter() 
    { 
       global $header_channel; 
       global $header_copyrightowner; 
       global $header_language; 
       global $header_update_mins; 
       global $header_timestamp; 
       global $header_date; 
       global $header_time; 
       global $header_comment; 
    
       print("<p/>Alle Rechte vorbehalten: "); 
       print("<a href=\"http://".$header_copyrightowner."\">".$header_copyrightowner."</a><p/>"); 
       print("Update alle ".$header_update_mins." Minuten"); 
       print("</body></html>"); 
    } 
    
    function printHeader() 
    { 
       global $header_channel; 
       global $header_copyrightowner; 
       global $header_language; 
       global $header_update_mins; 
       global $header_timestamp; 
       global $header_date; 
       global $header_time; 
       global $header_comment; 
    
       print("Aktuelle Beitr&auml;ge aus <b>".$header_channel."</b><p/>"); 
       print($header_comment."<p/>"); 
       print("Stand: ".$header_date." ".$header_time."<p/>"); 
    } 
    
    function printTopic() 
    { 
       global $topic_title; 
       global $topic_link; 
       global $topic_timestamp; 
       global $topic_date; 
       global $topic_time; 
       global $topic_poster; 
       global $topic_forum; 
       global $topic_forum_link; 
       global $topic_cat; 
       global $topic_cat_link; 
    
       print("<p>"); 
       print("<a href=\"".$topic_cat_link."\"\>".$topic_cat."</a>::"); 
       print("<a href=\"".$topic_forum_link."\"\>".$topic_forum."</a>::"); 
       print("<a href=\"".$topic_link."\"\>".$topic_title."</a><br>"); 
    
       print("von ".$topic_poster." am ".$topic_date." um ".$topic_time."<p>"); 
    } 
    
    // XML-Parser beginnt hier 
    
    function startElement($parser, $name, $attrs)  
    { 
       global $inside_header; 
       global $last_pcdata;
    
       switch ($name)  
       { 
       case "HEADER": 
          $inside_header = "true"; 
          break; 
       }
    
       $last_pcdata = "";
    } 
    
    function endElement($parser, $name)  
    { 
       global $print; 
       global $numberofa; 
       global $maxa; 
       global $last_pcdata; 
       global $inside_header; 
    
       global $topic_title; 
       global $topic_link; 
       global $topic_timestamp; 
       global $topic_date; 
       global $topic_time; 
       global $topic_poster; 
       global $topic_forum; 
       global $topic_forum_link; 
       global $topic_cat; 
       global $topic_cat_link; 
    
       global $header_channel; 
       global $header_copyrightowner; 
       global $header_language; 
       global $header_update_mins; 
       global $header_timestamp; 
       global $header_date; 
       global $header_time; 
       global $header_comment; 
    
       if ($numberofa < $maxa)  
       { 
          switch ($name)  
          { 
          case "HEADER": 
             printHeader(); 
             $inside_header = "false"; 
             break; 
          case "CHANNEL": 
             $header_channel = $last_pcdata; 
             break; 
          case "COPYRIGHTOWNER": 
             $header_copyrightowner = $last_pcdata; 
             break; 
          case "LANGUAGE": 
             $header_language = $last_pcdata; 
             break; 
          case "UPDATE_MINS": 
             $header_update_mins = $last_pcdata; 
             break; 
          case "COMMENT": 
             $header_comment = $last_pcdata; 
             break; 
          case "TOPIC": 
             printTopic(); 
             $numberofa++; 
             break; 
          case "TITLE": 
             $topic_title = $last_pcdata; 
             break; 
          case "LINK": 
             $topic_link = $last_pcdata; 
             break; 
          case "TIMESTAMP": 
             if ($inside_header == "true") 
                $header_timestamp = $last_pcdata; 
             else 
                $topic_timestamp = $last_pcdata; 
             break; 
          case "DATE": 
             if ($inside_header == "true") 
                $header_date = $last_pcdata; 
             else 
                $topic_date = $last_pcdata; 
             break; 
          case "TIME": 
             if ($inside_header == "true") 
                $header_time = $last_pcdata; 
             else 
                $topic_time = $last_pcdata; 
             break; 
          case "POSTER": 
             $topic_poster = $last_pcdata; 
             break; 
          case "FORUM": 
             $topic_forum = $last_pcdata; 
             break; 
          case "FORUM_LINK": 
             $topic_forum_link = $last_pcdata; 
             break; 
          case "CAT": 
             $topic_cat = $last_pcdata; 
             break; 
          case "CAT_LINK": 
             $topic_cat_link = $last_pcdata; 
             break; 
          } 
       } 
    
       $last_pcdata = ""; 
    } 
    
    function characterData($parser, $data)  
    { 
       global $last_pcdata; 
       $last_pcdata .= htmlentities($data); 
    } 
    
    pageHeader(); 
    
    $xml_parser = xml_parser_create(); 
    xml_set_element_handler($xml_parser, "startElement", "endElement"); 
    xml_set_character_data_handler($xml_parser, "characterData"); 
    
    if (!($fp = fopen($file, "r")))  
    { 
       die("could not open XML input ".$file); 
    } 
    
    while ($data = fread($fp, 4096))  
    { 
       if (!xml_parse($xml_parser, $data, feof($fp)))  
       { 
          die(sprintf("XML error: %s at line %d", 
              xml_error_string(xml_get_error_code($xml_parser)), 
              xml_get_current_line_number($xml_parser))); 
       } 
    } 
    
    xml_parser_free($xml_parser); 
    
    pageFooter(); 
    ?>
    

    Verwendet wird (eine leicht variierte Version) des Parsers z.B. auf der Startseite www.c-plusplus.net rechts.


Anmelden zum Antworten