28.11.2011 Jetzt neu! XMLResult_i
Die XMLResult_i Klasse ist vollständig kompatibel zur XMLResult-Klasse, verwendet für die Datenbank-Operationen jedoch die modernere mysqli-Erweiterung. Es ist damit möglich, mit Stored Procedures zu arbeiten, was bei komplexeren SQL-Statements wichtig sein kann. Es wird empfohlen, wenn möglich die XMLResult_i Klasse zu verwenden und nur auf die XMLResult-Klasse zurück zu greifen, wenn mysqli nicht aktiv ist oder aus anderen Gründen nicht verwendet werden kann.
Die Dokumentation gilt uneingeschränkt für beide Versionen des Skriptes
Die PHP-Klasse XMLResult erzeugt aus dem Ergebnis einer oder mehrerer mySQL-Abfragen XML-Ausgaben, die sich in Web-Services nutzen oder z. B. mit XSL(T) formatiert innerhalb einer Webseite anzeigen lassen. Hierbei spielt die Klasse ihre Stärke aus, indem sie einerseits ohne weiteres Zutun wohlgeformte XML-Dateien erzeugt und andererseits alle notwendigen Einstellungsmöglichkeiten bietet, um die XML-Ausgabe nach den eigenen Vorstellungen zu gestalten.
Eine ganz wesentliche Eigenschaft der XMLResult -Klasse ist die Tatsache, dass mit ihr auch verschachtelte Abfragen – und zwar in theoretisch beliebiger Verschachtelungstiefe – möglich sind. Es können hierbei beliebige und auch beliebig viele Schlüsselfelder innerhalb der Where-Klausel der Unterabfragen definiert werden. Die Vorgehensweise bleibt dabei sehr übersichtlich.
Die XMLResult -Klasse ermöglicht es dank ihrer umfangreichen Fähigkeiten, komplexe XML-Dateien zu erstellen, wobei es dem Anwender überlassen bleibt, ob er die XML-Daten als DOM-Objekt oder als XML-String zurückbekommen möchte.
Download:
Aktuelle Version: 2.1.
Systemvoraussetzungen: PHP ab Version 5
Probleme im Zusammenhang mit dem Encoding innerhalb der getXmlLAsHtmlString()-Methode behoben.
Ältere Versionen:
Version: 2.0.
Systemvoraussetzungen: PHP ab Version 5
- [void][static] setConnection(string dbhost, string dbuser, string dbpassword, string dbname)
- Mit dieser statischen Methode wird der Klasse der Connection-String übergeben.
- [XMLResult] getInstance([string query])
- Erzeugt eine Instanz der XMLResult-Klasse und gibt diese zurück.
- [String] __tostring()
- Gibt eine Kennung der jeweiligen Instanz zurück. Bsp.: „XMLResult3”
- [DocumentFragment] executeQuery([string query])
- Führt die SQL-Abfrage aus und speichert das resultierende DOM-Objekt, welches oder dessen Inhalt mit Hilfe weiterer Methoden abgefragt werden kann. Ruft ausserdem die executeQuery-Funktion von etwaigen Unterabfragen auf, so dass diese Methode bei verschachtelten Abfragen nur einmal auf dem obersten Objekt aufgerufen werden muss.
- [integer] getNumRows()
- Gibt die Anzahl der Zeilen (Datensätze) des Ergebnisses einer SQL-Abfrage zurück.
- [void] insertSubQuery(XMLResult XMLResult)
- Implementiert eine Unterabfrage innerhalb einer XMLResult-Instanz durch Übergabe einer weiteren XMLResult-Instanz, die die entsprechende SQL-Unterabfrage enthält. Es können mehrere Objekte (und damit Unterabfragen) auf einer Ebene durch mehrfachen Aufruf dieser Methode übergeben werden, sowie beliebig viele Instanzen (Unterabfragern) ineinander verschachtelt werden. Die Schlüsselfelder der jeweiligen Hauptabfrage, nach dessen Werten innerhalb einer Unterabfrage gesucht werden soll werden in dieser in geschweiften Klammern geschrieben:
SELECT * FROM tblTitle WHERE artist_id = {artist_id}
Das obige SQL-Beispiel sucht zu jedem in der Hauptabfrage gefunden Artist in der Unterabfrage die Titel, wobei der Ausdruck mit den geschweiften Klammern gegen den Wert der artist_id aus der Hauptabfrage ersetzt wird. - [void] setEncoding(string encoding)
- Legt die Zeichensatzcodierung für das zu erzeugende DOMDocument-Objektes fest. Defaulteinstellung ist „UTF-8”.
- [void] includeContentTypeDeclaration([bool ContentTypeDeclaration])
- Wenn diese Option gesetzt ist, wird bei der Ausgabe der XML-Daten mit der Funktion getXMLAsString() der Content-Type im Dateiheader auf „txt/xml” gesetzt.
- [void] getQueryHeader([bool queryHeader])
- Sorgt dafür, dass Informationen über die SQL-Abfrage in die XML-Ausgabe eingebetten werden.
- [void] setRootElementName([string rootElementName])
- Hiermit wird der Name des Wurzelelements der zu erzeugenden XML-Datei gesetzt. Standardmäßig wird der Name „document” vergeben.
- [void] setRecordName([string recordName])
- Hiermit wird der Name einer Zeile der XML-Ausgabe vergeben. Standardmäßig wird die Ausgabe eines Datensatzes in ein Element namens „record” zusammengefasst.
- [void] setCustomTagName(string fieldname, string tagname)
- Einzelne Feldnamen aus der Rückgabe der Datenbankabfrage können mit dieser Methode umbenannt werden, so dass das entsprechende XML-Tag dann den neuen Namen trägt. Es wird jedoch empfohlen, nach Möglichkeit schon im SQL-Statement mit Aliasnamen zu arbeiten, um die gewünschte Benennung zu erhalten.
- [void] fieldsAsElements([mixed fields])
- Diese Funktion nimmt einen boolschen Wert oder ein Array entgegen. Sie bestimmt, ob und ggf. welche Datenbankfelder als XML-Elemente ausgegeben werden sollen. Wird der Funktion „true” übergeben, so werden alle Datenbankfelder als XML-Elemente ausgegeben. Wird false (default) übergeben, so erfolgt keine Ausgabe als XML-Element. Alternativ kann der Funktion ein Array mit den Feldnamen übergeben werden, die als XML-Element ausgegeben werden sollen. Standardmäßig werden alle Datenbankfelder als XML-Elemente ausgegeben.
- [void] fieldsAsAttributes(mixed fields)
- Diese Funktion nimmt einen boolschen Wert oder ein Array entgegen. Sie bestimmt, ob und ggf. welche Datenbankfelder als XML-Attribute des „record”-Elements ausgegeben werden sollen. Wird der Funktion „true” (default) übergeben, so werden alle Datenbankfelder als XML-Attribute ausgegeben. Wird false übergeben, so erfolgt keine Ausgabe als XML-Attribut. Alternativ kann der Funktion ein Array mit den Feldnamen übergeben werden, die als XML-Attribut ausgegeben werden sollen. Standardmäßig werden alle Datenbankfelder als XML-Elemente ausgegeben.
- [void] fieldsWithCDATA(array fields)
- Durch Übergabe eines Arrays mit Feldnamen werden diese Felder bei der Ausgabe in eine CDATA-Sektion eingeschlossen.
- [void] omitRootElement([$bool val])
- Sorgt dafür, dass das Wurzelelement der HTML-Ausgabe unterdrückt wird. Die XML-Datei ist dann nicht mehr valide, da es immer genau ein Wurzelelement geben muss. Diese Funktion ist dort sinnvoll, wo mehrere XML-Dateien zu einer einzigen Datei verknüpft werden sollen, die dann ein eigenes Root-Element besitzt.. Hier sind die Root-Elemente der einzelnen Dateien dann z. T. überflüssig.
- [XML-DomDocument] getDomDocument()
- Gibt das resultierende DomDocument als Objekt zurück.
- [string] getXMLAsString()
- Gibt die resultierende XML-Ausgabe als String zurück.
- [string] getXmlAsHtmlString()
- Gibt eine HTML-codierte und formatierte Ausgabe der XML-Daten zurück. Dies hilft in erster Linie beim Debuggen, indem unkompliziert eine XML-Ausgabe innerhalb einer HTML-Seite erzeugt werden kann.
Anwendungsbeispiele:
Alle Beispiele setzen voraus, dass der XMLResult-Klasse mittels der statischen Methode „setConnection()” ein gültiger Connection-String übergeben worden ist. Die Ausgabefunktion „getXmlAsHtmlstring()” am Ende aller Beispiele steht hier beispielhaft für eine der drei Ausgabefunktionen ”getXMLAsString()”, „getXmlAsHtmlString()” und ”getDomDocument()”.
Eine einfache Datenbankabfrage wird wie folgt augeführt:
$query = "SELECT * FROM tblArtists"; $artists = XMLResult::getInstance($query); $artists->executeQuery(); echo artists->getXmlAsHtmlString();
Sollen das Rootelement und die Elemente, die einen Datensatz repräsentieren umbenannt werden, verwendet man folgenden Code.
$query = "SELECT * FROM tblArtists";
$artists = XMLResult::getInstance($query);
$artists->setRootElementName('artists');
$artists->setRecordName('artist');
$artists->executeQuery();
echo artists->getXmlAsHtmlString();
Um einzelne Elemente als XML-Attribute und andere als XML-Elemente auszugeben, müssen die Datenbankfelder mit den Methoden „fieldsAsAttributes()” und „fieldsAsElements” der jeweiligen Ausgabeoption zugewiesen werden.
$query = "SELECT * FROM tblArtists";
$artists = XMLResult::getInstance($query);
$artists->setRootElementName('artist');
$artists->setRecordName('artists');
$artists->fieldsAsElements(array('field1','field3','field5'));
$artists->fieldsAsAttributes(array('field2','field4'));
$artists->executeQuery();
echo artists->getXmlAsHtmlString();
Sollen alle Elemente als Attribute und nicht als XML-Elemente ausgegeben werden, so kann auf die Nennung und Übergabe der Feldnamen als Array verzichtet werden.
$query = "SELECT * FROM tblArtists";
$artists = XMLResult::getInstance($query);
$artists->setRootElementName('artist');
$artists->setRecordName('artists');
$artists->fieldsAsElements(false);
$artists->fieldsAsAttributes(true);
$artists->executeQuery();
echo artists->getXmlAsHtmlString();
Für Unterabfragen verschachtelt man zwei XMLResult-Klassen mittels der „insertSubQuery()”-Methode. Im folgenden wird dies anhand zweier Tabellen gezeigt, von der die eine (tblArtists) Bands und Musiker und die andere (tblTitles) die Titel der Artists enthält. Die Tabellen werden über das Datenbankfeld artist_id verknüpft, dass in beiden Tabellen vorhanden ist. Im Ergebnis erhält man eine verschachtelte XML-Struktur.
$query = "SELECT * FROM tblArtists";
$artists = XMLResult::getInstance($query);
$artists->setRootElementName('artist');
$artists->setRecordName('artists');
$artists->fieldsAsElements(false);
$artists->fieldsAsAttributes(true);
$query2 = "SELECT * FROM tblTitle WHERE artist_id = {artist_id}";
$title = XMLResult::getInstance($query2);
$title->setRootElementName('titles');
$title->setRecordName('title');
$artists->insertSubQuery($title);
$artists->executeQuery();
echo artists->getXmlAsHtmlString();
Unterabfragen können sehr zeitintensiv sein. Werden bspw. 20 Ergebnisse der Hauptabfrage dargestellt und sollen zu diesen die Ergebnisse einer od. mehrerer Unterabfragen gezeigt werden, so bedeutet dies, dass je Unterabfrage 20 neue SQL Statements an die Datenbank abgesetzt werden. Dies sollte mit Bedacht getan werden und einen den Aufwand rechtfertigenden Mehrwert bieten.
Als Alternative könnte, wenn die Daten nicht permanent aktualisiert werden, eine XML-Datei generiert und persisten gespeichert werden, so dass diese nicht bei jedem Aufruf durch die Datenbank-Abfragen aufgebaut werden muss. Es könnte stattdessen eine regelmäßige Aktualisierung mit einem bestimmten Zeitintervall erfolgen oder nur dann, wenn sich Änderungen im Datenbestand ergeben.
Als weitere Alternative können die relevanten Daten auch separat aus der DB geholt und in eine XML-Datei gespeichert werden. Es werden dann zunächst alle Daten der Hauptabfrage geholt und dann alle Daten der "Unterabfrage" wobei hier alle Sub-Daten auf einmal geholt werden. In der XML-Datei ergibt sich somit zwar keine geschachtelte Struktur, mittels geeigneter XSL-Abfragen lassen sich dann aber trotzdem die jeweiligen Daten der Unterabfrage den Daten der Hauptabfrage zuordnen und verschachtelt darstellen. Dies kann unter Umständen performanter sein, als die Datenbank mit einer Vielzahl an SQL-Skripten zu belasten.

