Wie simpel ist php SimpleXML?

Oktober 2000 – Meinrad und ich bereiten das erste XML Seminar vor. Ich hatte noch etwas mehr Haare, dafür weniger Erfahrung mit XML als heute. Also glaubte ich, wenn ich 14 Jahre später schnell etwas mit PHP und XML machen müsste, würde es einfach. Besonders, wenn das Ding SimpleXML heisst.

Das Lesen der Daten war dann allerdings zum Haare raufen – hätte ich noch welche.

XML reloaded

XML Datei

Der Knoten <productList> enthält im Moment nur die <products> Elemente und scheint daher etwas überflüssig. Vorgesehen sind aber noch andere Elemente innerhalb von <productList>, welche für diese Diskussion unerheblich sind.

Man beachte, dass das XML mit einem XSD Schema definiert ist und einen XML Default Namespace „xml.ursmeier.net/kunde/projekt“ enthält. Das heisst, alle Elemente ohne Prefix, sind automatisch im erwähnten Namespace um allfällige Namenskonflikte zu vermeiden. Das ist wichtig zu wissen, weil wir später mit XPath Abfragen arbeiten und diese den Default Namespace berücksichtigen müssen.

Simpel ist die Syntax

Eine XML File zu laden ist wirklich simpel.

Allerdings wird dabei kein DOM Model als Baumstruktur abgebildet, sondern die Daten werden als SimpleXML-Object instanziert. Das sieht man sehr einfach im NetBeans Debugger.

NetBeans Debugger zeigt die Struktur der XML Datei an
NetBeans Debugger zeigt die Struktur der XML Datei an

Mit dem simplexml_load_file wurde der Knoten <productList> der Variable $xml zugewiesen.

  1. $xml ist vom Typ SimpleXMLElement (es gibt nur 1 <productList>)
  2. $xml enthält den Knoten <products> als SimpleXMLElement (es gibt ebenfalls nur 1 <products> Element)
  3. $xml->products enthält einen Array product (es gibt eben 3 <product> Elemente im XML File)
  4. Jeder Array Eintrag in $xml->products ist wieder um vom Typ SimpleXMLElement

Hmmm, also ab und zu ist es SimpleXMLElement und ab und zu ein Array, der dann wieder SimpleXMLElement Einträge enthält. Woher weiss ich, wann ich was kriege?

SimpleXML?

Auf gut Deutsch: man muss die Struktur kennen. Schauen wir das genauer an!

 

 Simpel sind die Zugriffe

Wissend, dass $xml dem Element <productList> entspricht, kann ich einfach die ganze Objekt-Struktur abgrasen.

Der Output ist dann wie erwartet: 67, da im Array-Element 1 das Produkt mit der ID=2 liegt.

Interessant ist allerdings, was der NetBeans Debugger anzeigt. $productPrice ist ein SimpleXMLElement und dazu noch leer!

Man würde ein Decimal oder im schlimmsten Fall auch einen String für das Element  "price" erwarten. Aber nein, es ist ein SimpleXMLElement
Man würde ein Decimal oder im schlimmsten Fall auch einen String für das Element „price“ erwarten. Aber nein, es ist ein SimpleXMLElement

Wieso aber funktioniert dann das echo Statement?

Ganz einfach, weil bei echo (print usw.) implizit toString() aufgerufen wird. Das ist bei Objekten üblich und PHP nennt das „magic methods„. Wo das SimpleXMLElement allerdings die Daten für die toString() Funktion speichert, weiss ich nicht. Im Debugger wurde ja nichts angezeigt.

Anders gesagt: ohne eine Typen Konvertierung geht nichts, wenn man die „wirklichen Daten“ (unterste Stufe im XML Baum) haben will.

Nicht ganz simpel sind die Datenzugriffe

Im folgenden Beispiel suchen wir das Produkt 1 und seinen Preis. Da eine XPath Query verwendet wird, und das XML Dokument einen Default Namespace aufweist, muss dieser mittels registerXPathNamespace bekannt gemacht werden.

Wie gesagt, von der Syntax und der Datenstruktur könnte man annehmen, $product1Price wäre ein Decimal oder String.

In Tat und Wahrheit ist es ein SimpleXMLElement. Weil SimpleXMLElement immer SimpleXMLElemente zurückschickt. Das ist, was man unter Simpel versteht.

Nun suchen wir Produkt 2.

 

Schlussendlich vergleichen wir die beiden Preise.

Das führt zur Ausgabe „28 und 67 sind gleich!„, weil eben keine Decimals/Strings sondern SimpleXMLElemente verglichen werden.

SimpleXML?

Fazit

Mit SimpleXML muss man selber wissen, wann man auf einen skalaren Datentypen stösst und diesen umwandeln. Tut man es nicht, bekommt man noch immer ein Objekt vom Typ SimpleXMLElement.

In diesem Fall wird der Preis zu einem String konvertiert. PHP findet selber heraus, dass in den Variablen Zahlen gespeichert sind und vergleicht richtig.

Das führt dann zu richtigen Ausgabe „67 > 28“.

Urs Verfasst von: