[PHP] XML lesen
-
Hi, ich benutze zum lesen von xml folgenden Code:
<? $link_prefix = "· "; $link_postfix = "<BR>\n"; $show_abstract = true; $ab_link_prefix = ""; $ab_link_postfix = "<BR>\n"; $ab_prefix = ""; $ab_postfix = "<BR><BR>\n"; $ab_more = "[mehr...]"; $ab_more_prefix = " \n"; $cache_file = "tmp.cache"; $cache_time = 0; $max_items = 10; $max_readsize = 10000; $target = "_top"; // End of customizations $backend = "test.xml"; $items = 0; $time = split(" ", microtime()); srand((double)microtime()*1000000); $cache_time_rnd = 300 - rand(0, 600); if ( (!(file_exists($cache_file))) || ((filectime($cache_file) + $cache_time - $time[1]) + $cache_time_rnd < 0) || (!(filesize($cache_file))) ) { $fpread = fopen($backend, 'r'); if(!$fpread) { // echo "$errstr ($errno)<br>\n"; // exit; } else { $fpwrite = fopen($cache_file, 'w'); if(!$fpwrite) { // echo "$errstr ($errno)<br>\n"; // exit; } else { $string = fread($fpread, $max_readsize); $pattern = "/<ARTIKEL>(.*?)<\/ARTIKEL>/is"; if (preg_match_all($pattern, $string, $match, PREG_SET_ORDER)) for($i= 0; $i< min(count($match), $max_items); $i++){ $artikel= $match[$i][1]; $pattern = "/<HEADLINE>(.*?)<\/HEADLINE>/i"; preg_match($pattern, $artikel, $lmatch); $title= $lmatch[1]; $pattern = "/<URL>(.*?)<\/URL>/i"; preg_match($pattern, $artikel, $lmatch); $link= $lmatch[1]; if($items== 0 && $show_abstract){ $pattern = "/<ABSTRACT>(.*?)<\/ABSTRACT>/i"; preg_match($pattern, $artikel, $lmatch); $abstract= $lmatch[1]; fputs($fpwrite, $ab_link_prefix."<A HREF=\"".$link."\" TARGET=\"".$target."\">".$title."</A>".$ab_link_postfix); fputs($fpwrite, $ab_prefix.$abstract.$ab_more_prefix."<A HREF=\"".$link."\" TARGET=\"".$target."\">".$ab_more."</A>".$ab_postfix); }else fputs($fpwrite, $link_prefix."<A HREF=\"".$link."\" TARGET=\"".$target."\">".$title."</A>".$link_postfix); $items++; } } fclose($fpread); } fclose($fpwrite); } if (file_exists($cache_file)) { include($cache_file); } ?>
XML zum lesen: http://www.filesforfree.de/test.xml
Leider funzt der aber nicht, ok, sind andere Variablen, aber auch wenn ich die in meinem script verändere gehts nicht, woran liegt das, kann mir einer helfen?
-
Hi,
ich würde an Deiner Stelle ein XML-File grundlegend anders einlesen, schließlich bietet PHP dafür extra Funktionen.
Ich hau Dir hier mal ein Beispiel für eine Navigation hin, ich hoffe es ist ok, wenn das n bissl länger wird jetzt.
Das werden jetzt 3 Dateien. (test.php), (xml.class.php), und das xml-file (menu.xml).
menu.xml
<?xml version="1.0" standalone="yes"?> <!DOCTYPE menu SYSTEM "menu.dtd"> <menu> <item name="Menu 1"></item> <item name="Menu 2"></item> <item name="Menu 3"> <subitem>Menu 3-1</subitem> <subitem>Menu 3-2</subitem> </item> <item name="Menu 4"> <subitem>Menu 4-1</subitem> </item> <item name="Menu 5"> <subitem>Menu 5-1</subitem> <subitem>Menu 5-2</subitem> <subitem>Menu 5-3</subitem> </item> <item name="Menu 6"></item> </menu>
xml.class.php
<?php class XML { var $parser; var $xml_file; var $html; var $open_tag; var $close_tag; function XML ( $file = null ) { $this->parser = ""; $this->html = ""; if ( $file != "" ) $this->xml_file = $file; $this->parser = xml_parser_create ( ); $this->open_tag = Array ( "menu" => "<table cellspacing='0' cellpadding='2' border='0'><tr>", "item" => "<td valign='top'><font size='3'>", "subitem" => "<br /><font size='2'>" ); $this->close_tag = Array ( "menu" => "</tr></table>", "item" => "</font></td>", "subitem" => "</font>" ); } function destroy ( ) { xml_parser_free ( $this->parser ); } function element_start ( $parser, $name, $attrib ) { if ( count($attrib) > 0 ) $this->html .= $this->open_tag[$name] . $attrib['name']; else { if ( $str = $this->open_tag[$name] ) $this->html .= $str; } } function element_close ( $parser, $name ) { if ( $str = $this->close_tag[$name] ) $this->html .= $str; } function element_data ( $parser, $data ) { $this->html .= $data; } function parse ( ) { xml_set_object ( $this->parser, &$this ); xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); xml_set_character_data_handler ( $this->parser, "element_data" ); xml_set_element_handler ( $this->parser, "element_start", "element_close" ); if ( !($fp = fopen ( $this->xml_file, "r" )) ) die ( "Opening XML-File failed!\n" ); while ( $data = fread ( $fp, 2048 ) ) { if ( !xml_parse ( $this->parser, $data, feof($fp) ) ) { die(sprintf("XML error: %s at line %d", xml_error_string( xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser))); } } } } ?>
test.php
<?php include "xml.class.php"; $xml = new XML ( "menu.xml" ); $xml->parse ( ); echo $xml->html; $xml->destroy ( ); ?>
In der xml.class.php steht die ganze Logik drin, die Dir Dein Xml-File zerpflückt. Sorry für das blöde Beispiel, ich habe die Struktur des XML jetzt nicht sehr glorreich gewählt, da menüs mit mehr als 2 Ebenen da n bissl schlecht machbar wären. Aber zum zeigen, sollte es reichen.
Schau Dir am besten dazu in der PHP-Doku mal folgende Funktionen an:
xml_set_object()
xml_set_character_data_handler()
xml_set_element_handler()Das Prinzip ist so, dass Du nen Handler definierst für öffnende Tags, CharacterData-Bereiche (alles zwischen öffnendem und schließendem Tag) und schließende Tags.
Ich hoffe das Dir das irgendwie hilft.
** Um das zu testen, muss Expat installiert sein. Das ist aber eigentlich Standard.Gruß,
mid
-
Puh, da arbeite ich mich mal durch...
Wir erstelle nämlich gerade ein downloadarchiv, und das soll programminfos mit xmls einlesen können.
Ok, Danke!!!
-
Dann solltest Du es auf jeden Fall so machen. Ist im Prinzip nicht so schwer, wenn man einmal hinter gestiegen ist.
Viel Erfolg,
mid
-
hmm... komisch, ist das bei dir auchso, dass der ganze xml text angezeigt wird?
Eigendlich wollte ich die variale:
XML_DIZ_INFO->Program_Info->Program_Nameaus dieser xml fischen: http://www.filesforfree.de/test.xml
kannste mir da nochmal schnell sagen wie das geht?
-
Weil heut Samstag ist.
Du musst im Prinzip nur die xml.class.php von weiter oben ändern:
<?php class XML { var $parser; var $xml_file; var $html; var $open_tag; var $close_tag; var $open_flag = Array(); function XML ( $file = null ) { $this->parser = ""; $this->html = ""; if ( $file != "" ) $this->xml_file = $file; $this->parser = xml_parser_create ( ); $this->open_tag = Array ( "menu" => "<table cellspacing='0' cellpadding='2' border='0'><tr>", "item" => "<td valign='top'><font size='3'>", "subitem" => "<br /><font size='2'>" ); $this->close_tag = Array ( "menu" => "</tr></table>", "item" => "</font></td>", "subitem" => "</font>" ); } function destroy ( ) { xml_parser_free ( $this->parser ); } function element_start ( $parser, $name, $attrib ) { // diese Methode wird immer aufgerufen, wenn der Parser über ein öffnendes Tag läuft // $name ist der Elementname // $attrib ist im besten Falle ein assoziatives Array mit den ganzen Attributen if( $name=='Program_Name' ) { // wenn Du in diese if-Klausel kommst, dann bist Du im XML-Baum im Tag <Program_Name> // mach hier damit, was Du willst echo '<b>Programm-Name: '; $this->open_flag['progname'] = true; } } function element_close ( $parser, $name ) { // diese Methode wird immer aufgerufen, wenn der Parser über ein schließendes Tag läuft if( $name=='Program_Name' ) { // wenn Du in diese if-Klausel kommst, dann bist Du im XML-Baum im Tag </Program_Name> // mach hier damit, was Du willst echo '</b>'; } } function element_data ( $parser, $data ) { // hier werden alle Daten behandelt, die zwischen einem // öffnenden und schließenden Tag des gleichen Elementes stehen if( $this->open_flag['progname'] == true ) { echo $data; unset( $this->open_flag['progname'] ); } } function parse ( ) { xml_set_object ( $this->parser, &$this ); xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); xml_set_character_data_handler ( $this->parser, "element_data" ); xml_set_element_handler ( $this->parser, "element_start", "element_close" ); if ( !($fp = fopen ( $this->xml_file, "r" )) ) die ( "Opening XML-File failed!\n" ); while ( $data = fread ( $fp, 2048 ) ) { if ( !xml_parse ( $this->parser, $data, feof($fp) ) ) { die(sprintf("XML error: %s at line %d", xml_error_string( xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser))); } } } } ?>
Und noch eine Bitte, verwenden bitte in Deiner XML-Datei nicht den Zeichensatz "windows-1252". Das kann bei manchen Parsern Probs machen. Günstig ist immer "ISO-8859-1" (das ist Latin 1) oder "UTF-8" o.ä
Gruß,
mid
-
Coooool, danke! Genau das hab ich gesucht!!!!
-
um XML darzustellen kann man fei auch die style-tags verwenden... (dann kann man im browser die xml-datei aufrufen, und bekommt ne webseite raus)