ContentLion - Open Source CMS

PHP und XML sind eine gute Kombination. Ich habe noch keine Programmiersprache gesehen, in der man so leicht auf XML zugreifen kann. Deswegen möchte ich heute einmal die Basics vorstellen, mit denen Du von PHP XML-Dateien verarbeiten kannst.

XML wird häufig als Schnittstelle zwischen verschiedenen Programmen. Wenn du selbst schon mal eine API angesteuert hast, wirst du vielleicht etwas damit zu tun gehabt haben.

Zunächst einmal möchte ich euch eine XML-Datei an die Hand geben, an welcher wir heute unsere Beispiele ausprobieren. Es ist ein XML-Sitemap, wie sie bei Google eingereicht werden kann. Mit diesem Ausschnitt werde ich testen:

<?xml version="1.0" encoding="UTF-8"?>
<urlset>
  <url>
    <loc>http://blog.stevieswebsite.de/</loc>
    <lastmod>2012-02-04T16:22:08+00:00</lastmod>
    <changefreq>daily</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>http://blog.stevieswebsite.de/2012/02/lokale-suchmaschinen/</loc>
    <lastmod>2012-02-04T16:22:08+00:00</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.2</priority>
  </url>
</urlset>

Die Datei kannst du einfach unter sitemap.xml speichern, genauso wie die weiteren PHP-Dateien, die es später auslesen sollen.

simplexml_load_file – Das einfache Lesen

<?PHP
  $sitemap = simplexml_load_file("sitemap.xml");
	
  foreach($sitemap->url as $url){
    ?>
      Url: <? echo $url->loc; ?><br />
      Zuletzt bearbeitet: <? echo $url->lastmod; ?><br />
      &Auml;nderungsfrequenz: <? echo $url->changefreq; ?><br />
      Priorit&auml;t: <? echo $url->priority; ?>
      <hr />
    <?PHP
  }
?>

simplexml_load_file lädt das XML-Dokument in ein Objekt rein. Jeder Tag ist eine Eigenschaft. Beinhaltet er Unterelemente, ist es ein Array.
Ein solches Array ist in dem Fall $sitemap->url. Beinhaltet sind nun alle url-Tags. In den Untertags kann man dann wiederum auf die darin enthaltenen Elemente zugreifen (z.B. $url->loc)

XPath – Element Adressierung

XPath kann man gut nutzen, wenn man in größeren Objekten ein einzelnes Feld auslesen möchte. Dabei gibt man dann den Path zum Element an, ähnlich wie es bei einer Url der Fall ist. Das obige Beispiel könnte man in XPath folgendermaßen lösen:

<?PHP
  $sitemap = simplexml_load_file("sitemap.xml");
	
  foreach($sitemap->xpath("/urlset/url") as $url){
    ?>
      Url: <? echo $url->loc; ?><br />
      Zuletzt bearbeitet: <? echo $url->lastmod; ?><br />
      &Auml;nderungsfrequenz: <? echo $url->changefreq; ?><br />
      Priorit&auml;t: <? echo $url->priority; ?>
      <hr />
    <?PHP
  }
?>

In dem Fall würde ich die erste Variante nehmen. Wenn es sich um große XML-Dokumente mit vielen verschachtelten Elementen arbeitet, würde ich XPath nehmen. Sonst müsste man genauso viele verschachtelte Schleifen wie Elemente im Dokument verwenden, was den Ablauf sehr unübersichtlich machen kann.

Die XML-Datei erweitern

Wir möchten die XML-Datei jetzt um einen Eintrag erweitern. Hierfür gibt es in PHP die Funktion addChild:

<?PHP
  header ("Content-Type:text/xml");
  $sitemap = simplexml_load_file("sitemap.xml");
	
  $newUrl = $sitemap->addChild("url");
  $newUrl->addChild("loc","http://blog.stevieswebsite.de/2012/02/php-und-xml/");
  $newUrl->addChild("lastmod","2012-02-11T17:25:00+00:00");
  $newUrl->addChild("changefreq","monthly");
  $newUrl->addChild("prority","0.2");
	
  echo $sitemap->asXml();

?>

In der ersten Zeile teilen wir mit header mit, dass der Browser die Datei als XML interpretieren soll. Ansonsten würde man nachher nur den Text ohne Tags sehen (außer im Quelltext). addChild benötigt den Namen des XML-Tags und liefert ein SimpleXMLELemetn zurück, auf welches wir weitere Childs hinzufügen können. So machen wir es mit den Unterelementen auch.

Mit asXML können wir dann das XML generieren. Mit echo wird es dann ausgegeben.

Warum PHP-Basics?

Ich habe mich dazu entschieden jetzt ab und an mal ein paar Basic-Artikel zu PHP zu erstellen. So kann ich auch Einsteigern in PHP eine gute Grundlage bieten. Fortgeschrittene können vielleicht einige Details lernen, die sie vorher nicht kannten. Ich hab zum Beispiel das mit dem addChild heute zum ersten Mal gemacht ;-)

  1. Lucas
    11. Februar 2012 @ 20:10

    Ich kannte SimpleXML schon, mein Probelm war aber dass ich nicht auf externe XML-Dateien zugreifen konnte. Weder bei meinem Strato-Space noch von einem eigenen Server aus war dies möglich. Hat dazu jemand eine Idee?

  2. Stefan Wienströer
    11. Februar 2012 @ 22:56

    In der PHP.ini muss die Einstellung allow_url_fopen auf On stehen. Kannst ja auch mal mit ini_set probieren.

  3. H.-Peter Pfeufer
    12. Februar 2012 @ 07:51

    Externe XML-Dateien vorher mit cURL abholen, dann braucht man nicht in der php.ini rumspielen oder gar im Script selbst an den Einstellungen rumdrehen. Am besten man packt das in ne Funktion in der auch gleich abgefragt wird, ob man cURL verwenden muss, oder das Ganze doch einfacher ran bekommt.

    Kleines Beispiel:

    if(!function_exists('_helper_curl')) {
    function _helper_curl($var_sUrl = '') {
    $var_sUserAgent = 'Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20100101 Firefox/5.0;

    if(ini_get('allow_url_fopen')) {
    $cUrl_Data = file_get_contents($var_sUrl);
    } else {
    if(function_exists('curl_init')) {
    $cUrl_Channel = curl_init($var_sUrl);
    curl_setopt($cUrl_Channel, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($cUrl_Channel, CURLOPT_HEADER, 0);
    curl_setopt($cUrl_Channel, CURLOPT_USERAGENT, $var_sUserAgent);
    curl_setopt($cUrl_Channel, CURLOPT_TIMEOUT, 10);

    $cUrl_Data = curl_exec($cUrl_Channel);

    if(curl_errno($cUrl_Channel) !== 0 || curl_getinfo($cUrl_Channel, CURLINFO_HTTP_CODE) !== 200) {
    $cUrl_Data === false;
    } // END if(curl_errno($ch) !== 0 || curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200)

    curl_close($cUrl_Channel);
    }
    } // END if(ini_get('allow_url_fopen'))

    return $cUrl_Data;
    } // END function _helper_curl($var_sUrl = '')
    } // END if(!function_exists('_helper_curl'))

    Aufgerufen wird dann dann einfach via:


    $xml = _helper_durl('http://www.die-gewuenschte-domain.de/file.xml');
    // Do what ever you want :-)

  4. Sascha
    4. Oktober 2012 @ 10:02

    Erstmal vielen Dank für die Dokumentation. Hat alles wunderbar funktioniert.
    Ich hab jetzt nur noch ein Problem. Mein XML ist aber noch verschachtelt
    Hier mal der Link:
    http://www.valkcard.de/xml-test/temp.xml
    darin gibt es unter pharmacy noch mal eine absplittung Servicepartner. Wie kann ich die dann auch nochmal auslesen?

  5. Stefan Wienströer
    7. Oktober 2012 @ 19:35

    Schau dir mal das an: http://php.net/manual/de/simplexmlelement.xpath.php

Hinterlasse einen Kommentar