XML (EXPAT) in PHP Probleme
Philipp Schöfer
- xml
Hallo,
ich habe hier eine XML Datei:
http://www.camelot-europe.com/herald/servers.xml
Das Teil zeigt alles mögliche an, manches brauche ich jedoch nicht. Durch eine Variable hab ich das jetzt einigermassen in griff bekommen (es sollen eigentlich nur die Deutschen Server angezeigt werden), dennoch hab ich das gefühl es geht einfacher. Und zwarist es ja so, dass die <server> tags doch recht gross sind. Und wenn ich jetzt sage mich interessiert der englische server nicht, parst er mir trotzdem ALLE inhalte dieses Servers (durch eine Variable unterdrücke ich nur die anzeige von den inhalten, geparst werden sie ja trotzdem). Meine Frage ist jetzt, ob ich nicht einfach "sagen" kann, den Tag und alle untergeordneten sollst du gänzlich überspringen.
Dann habe ich noch das Problem das einer der einträge "SCHWERt & ROSE" als inhalt hat. Das wird leider ganz wo anders angezeigt, und das ist acuh kein wunder den er parst SCHERT und & und ROSE einzeln.
http://armyofdarkness.clanintern.de/start.php?goto=herald
Muss ich da irgendwelche umlaute definieren oder wie ?
Und dann hier noch mein Script:
<table border="0" >
<?php
// start_element() - wird vom XML-Parser bei öffnenden
// Tags aufgerufen
function start_element( $parser, $name, $attribute )
{
global $curtag;
global $german;
switch($name)
{
case "SERVER";
if($attribute["TYPE"] == "German")
{
print "<tr><td>";
print "<br><b>";
print $attribute["NAME"];
print "</b><br>";
print "</td></tr><tr>";
$german = "WAHR";
}
else
{
$german = "FALSCH";
}
$curtag = $name;
break;
case "KEEP";
if($german == "WAHR")
{
print "<td>";
print $attribute["NAME"]." - ".$attribute["REALM"];
print "</td>";
}
else
{
}
$curtag = $name;
break;
case "RELIC";
if($german == "WAHR")
{
print "<td>";
print $attribute["NAME"]." - ".$attribute["TYPE"]." - ".$attribute["REALM"];
print "</td>";
}
else
{
}
$curtag = $name;
break;
case "POPULATION";
$curtag = $name;
break;
case "STATUS";
$curtag = $name;
break;
case "OWNER";
if($german == "WAHR")
{
print "<td>";
}
else
{
}
$curtag = $name;
break;
case "CLAIMANT";
if($german == "WAHR")
{
print "<td>";
}
else
{
}
$curtag = "CLOSE";
break;
default:
$curtag = $name;
break;
}
}
// end_element() - wird vom XML-Parser bei schließenden
// Tags aufgerufen
function end_element( $parser, $name )
{
}
// daten() - wird vom XML-Parser für CDATA-Bereiche aufgerufen
function daten( $parser, $data )
{
global $curtag;
global $german;
if(($german == "FALSCH") or ($curtag == "POPULATION") or ($curtag == "STATUS"))
{
// Datenbereich ausgeben
}
else
{
switch($data)
{
case "Albion";
print $data;
print "</td></tr><tr>";
break;
case "Midgard";
print $data;
print "</td></tr><tr>";
break;
case "Hibernia";
print $data;
print "</td></tr><tr>";
break;
default:
if($curtag == "CLOSE")
{
print $data;
print "</td></tr><tr>";
}
else
{
}
}
}
}
// Instanz des XML-Parsers erzeugen
$parser = xml_parser_create();
// Parameter des XML-Parsers setzen
xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, true );
// Handler für Elemente ( öffnende / schließende Tags ) setzen
xml_set_element_handler( $parser, "start_element", "end_element" );
// Handler für Daten ( CDATA ) setzen
xml_set_character_data_handler( $parser, "daten" );
// Versuchen, die Datei zu öffnen
if (! ( $fp = fopen( "http://www.camelot-europe.com/herald/servers.xml", "r" ) ) )
{
// Fehler -> Ausführung abbrechen
die( "XML Fehler: Konnte Datei nicht öffnen." );
}
// Datei zeilenweise auslesen
while( $data = fread( $fp, 4096 ) )
{
// Versuchen, die aktuelle Zeile zu parsen
if( !xml_parse( $parser, $data, feof( $fp ) ) )
{
// Fehler -> Ausführung abbrechen
die( "XML Fehler: " .
xml_error_string( xml_get_error_code( $parser ) ) .
" in Zeile " .
xml_get_current_line_number( $parser )
);
}
}
// Vom XML-Parser belegten Speicher freigeben
xml_parser_free( $parser );
?>
</table>
Sehr umständlich oder ? Geht das nicht irgendwie leichter ? Es ist eben eine total neue materie für mich, und leider habe ich immernoch kein Buch oder so gefunden das sich genau mit dem Thema befasst. Ich kopieren nur alles mäglcihe in meinen Code und versuche es zu verstehen, leider kenne ich dadurch die ganzen möglichkeiten nicht, oder kenne sie erst dann wenn es schon zu spät ist.
Für ein paar einfache Links zum Thema XML, PHP (EXPAT), wäre ich schon sehr dankbar.
Grüße
Philipp Schöfer
Hallo Phlipp,
Das Teil zeigt alles mögliche an, manches brauche ich jedoch nicht. Durch eine Variable hab ich das jetzt einigermassen in griff bekommen (es sollen eigentlich nur die Deutschen Server angezeigt werden), dennoch hab ich das gefühl es geht einfacher. Und zwarist es ja so, dass die <server> tags doch recht gross sind. Und wenn ich jetzt sage mich interessiert der englische server nicht, parst er mir trotzdem ALLE inhalte dieses Servers (durch eine Variable unterdrücke ich nur die anzeige von den inhalten, geparst werden sie ja trotzdem). Meine Frage ist jetzt, ob ich nicht einfach "sagen" kann, den Tag und alle untergeordneten sollst du gänzlich überspringen.
Erst die Antwort: Ja, du könntest.
Aber dazu müsstest du einen Parser nehmen, der mit einem SAX API arbeitet (was kaum der Fall sein wird, wenn du nicht mit Java arbeitest)
Die andere Methode ist der Zugriff über DOM auf die XML-Datei.
Der Unterschied zwischen den beiden Methoden ist, dass beim zugriff über DOM erst die ganze XML-Datei in dem Speicher eingelesen werden muss, bevor du damit weiterarbeiten kannst und das kostet bei großen XML-Dateien (wobei deine nicht wirklich groß ist (51Kb ist wirklich kaum eine Größe)), nicht nur Memory, aber auch Zeit.
SAX arbeitet anders: er geht event-basiert vor, d.h. du kannst dem Parser einen "event" mitteilen bei dem er etwas machen soll (nach dem Motto: sag mir, wenn etwas passiert). Also, er geht vom Anfang des Dokuments vor und liest auch alles - aber nur durch- und meldet immer wieder zurück was er gefunden hat.
In deinem Fall: du sagst ihm, dass er bei type="german" etwas tun soll. Er geht also und meldet
STOP!
-----
Tja, so weit über DOM und SAX.
Infos unter: http://www.saxproject.org/
Über andere Spachen als Java: http://www.saxproject.org/?selected=langs
Für ein paar einfache Links zum Thema XML, PHP (EXPAT), wäre ich schon sehr dankbar.
http://www.phpbuilder.com/columns/justin20000428.php3 Achtung der Artikel ist auf mehrere Seiten unterteilt.
http://www.xml.com/pub/a/1999/09/expat/index.html
Grüße
Thomas
Hallo Phlipp,
- es schein heute der Tag von den Philipps zu sein - :-)
Auch dein Problem ist an sich keine Frage von/zu XML.Das Teil zeigt alles mögliche an, manches brauche ich jedoch nicht. Durch eine Variable hab ich das jetzt einigermassen in griff bekommen (es sollen eigentlich nur die Deutschen Server angezeigt werden), dennoch hab ich das gefühl es geht einfacher. Und zwarist es ja so, dass die <server> tags doch recht gross sind. Und wenn ich jetzt sage mich interessiert der englische server nicht, parst er mir trotzdem ALLE inhalte dieses Servers (durch eine Variable unterdrücke ich nur die anzeige von den inhalten, geparst werden sie ja trotzdem). Meine Frage ist jetzt, ob ich nicht einfach "sagen" kann, den Tag und alle untergeordneten sollst du gänzlich überspringen.
Erst die Antwort: Ja, du könntest.
Aber dazu müsstest du einen Parser nehmen, der mit einem SAX API arbeitet (was kaum der Fall sein wird, wenn du nicht mit Java arbeitest)
Die andere Methode ist der Zugriff über DOM auf die XML-Datei.
Der Unterschied zwischen den beiden Methoden ist, dass beim zugriff über DOM erst die ganze XML-Datei in dem Speicher eingelesen werden muss, bevor du damit weiterarbeiten kannst und das kostet bei großen XML-Dateien (wobei deine nicht wirklich groß ist (51Kb ist wirklich kaum eine Größe)), nicht nur Memory, aber auch Zeit.SAX arbeitet anders: er geht event-basiert vor, d.h. du kannst dem Parser einen "event" mitteilen bei dem er etwas machen soll (nach dem Motto: sag mir, wenn etwas passiert). Also, er geht vom Anfang des Dokuments vor und liest auch alles - aber nur durch- und meldet immer wieder zurück was er gefunden hat.
In deinem Fall: du sagst ihm, dass er bei type="german" etwas tun soll. Er geht also und meldet
- server name="Excalibur" type="English" updated="17-11-2002 1:40:01"
- server name="Broceliande" type="French" updated="17-11-2002 01:40:00"
- server name="Avalon" type="German" updated="17-11-2002 01:40:00"
STOP!
Tja, so weit über DOM und SAX.
Infos unter: http://www.saxproject.org/
Über andere Spachen als Java: http://www.saxproject.org/?selected=langsFür ein paar einfache Links zum Thema XML, PHP (EXPAT), wäre ich schon sehr dankbar.
http://www.phpbuilder.com/columns/justin20000428.php3 Achtung der Artikel ist auf mehrere Seiten unterteilt.
http://www.xml.com/pub/a/1999/09/expat/index.html
Grüße
Thomas
Danke dir Thomas, ich denke das hat mir in dem ganzen wirrwar etwas weitergeholfen. Also lassen sich quasi auch eigene Events definieren. Nicht nur StartElement und EndElement. Und danke auch für die Links...
Grüße
Philipp