Tegenwoordig wordt voor steeds meer toepassingen van XML documenten gebruik gemaakt, zoals in RSS Feeds of Open Office documenten, maar ook Word zal straks z'n documenten in een XML formaat gaan opslaan. Voor de mensen die nog nooit met XML gewerkt hebben: XML is een bepaalde manier om gegevens gestructureerd vast te leggen. Deze manier is gedefinieerd en mag iedereen gebruiken. Het is ontworpen om zowel door een programma als door een mens leesbaar te zijn. XML is niet alleen geschikt om gegevens in op te slaan maar wordt de laatste tijd ook meer en meer gebruikt om gegevens via het internet te versturen.
XMLWriter
In de nieuwe versies van php4 (4.3+) en php5+ zit tegenwoordig een api voor de XMLWriter. Deze api zorgt er voor dat je op een simpele manier XML documenten kan maken die er ook nog goed uitzien. Verder is het mogelijk om deze documenten rechtstreeks naar een url te sturen via PHP streams of ze te bufferen en ze te returnen als een string. De XMLWriter is in php4 te gebruiken door functies aan te roepen en in php5 kun je de OO methode gebruiken. Hieronder zal ik alleen de php5 variant laten zien, maar het voorbeeld is eenvoudig te herschrijven zodat het ook in php4 zal werken.
Eenvoudig praktijkvoorbeeld
In de
blog van mijn collega Jeroen hebben jullie kunnen lezen hoe hij de RSS feeds uitleest. Ik zal nu in het kort laten zien hoe je snel een RSS XML document kunt genereren via de XMLWriter API in php5.
PHP:
<?php
class rssWriter extends XMLWriter
{
public function __construct($uri, $indent = true, $identString = NULL)
{
if(empty($uri)) throw new Exception("URI is verplicht");
if(!$this->openUri($uri)) throw new Exception("URI is niet te openen");
if($indent) $this->setIndent(true);
if(!empty($identString)) $this->setIndentString($identString);
}
?>
Als basis hebben we de constructor waar je aan meegeeft: de uri, of hij moet uitlijnen en hoe we moeten uitlijnen. De uri kan eventueel ook een filename zijn of een externe url (http://....)
PHP:
<?php
public function header($title, $link, $description, $generator)
{
$this->startDocument('1.0', 'UTF-8');
$this->startElement("rss");
$this->writeAttribute("version","2.0");
$this->startElement("channel");
$this->writeElement("title",$title);
if(!empty($link)) $this->writeElement("link",$link);
$this->writeElement("description",$description);
if(!empty($generator)) $this->writeElement("generator",$generator);
$this->writeElement("lastBuildDate",date(DATE_RFC822));
}
?>
Om een RSS feed te schrijven zullen we een header moeten schrijven met de juiste gegevens. Als eerst geven we aan dat het om een xml versie 1.0 document gaat die gecodeerd is als UTF-8. Daarna willen we een element 'rss' toevoegen dat als attribute version="2.0" heeft. Het element wordt toegevoegd met de startElement functie en de attributen van het element kun je meegeven door de writeAttribute functie te gebruiken. Met de writeElement functie voegen we overige headers toe aan het document. (De boven gebruikte DATE_RFC822 param in de date() functie werkt alleen in php 5.1.1+).
PHP:
<?php
public function item($title, $description, $link, $timestamp)
{
$this->startElement("item");
$this->writeElement("title",$title);
if(!empty($link)) $this->writeElement("link",$link);
$this->writeElement("description",$description);
if(empty($timestamp)) $timestamp = time();
$this->writeElement("pubDate",date(DATE_RFC822,$timestamp));
$this->endElement();
}
?>
En natuurlijk willen we ook items kunnen toevoegen aan onze feed, dus implementeren we een item functie. De functies die hier gebruikt worden verschillen niet van de header behave dat we nu andere elementen toevoegen.
PHP:
<?php
public function close()
{
$this->endDocument();
$this->flush();
}
}
?>
In de close functie sluiten we het document en met 'flush' sturen we het geheel naar de opgegeven uri.
Nu hebben we dus een eenvoudige class die afgeleid is van de XMLWriter API en deze kunnen we nu als volgt gebruiken:
PHP:
<?php
$writer = new rssWriter("php://output",true," ");
$writer->header("Achievo RSS",
"http://www.achievo.org",
"Achievo Nieuws RSS Feed",
"ATK RSS Writer");
$writer->item("Achievo 1.2.0 Released",
"Eerste nieuws item",
"http://www.achievo.org/download/releasenotes/1_2_0",
mktime(0,0,0,4,24,2006));
$writer->item("Achievo 1.2.1 Released",
"Tweede nieuws item",
"http://www.achievo.org/download/releasenotes/1_2_1",
mktime(0,0,0,5,29,2006));
$writer->close();
?>
Bovenstaande code zal dan het volgende XML document genereren:
CODE:
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Achievo RSS</title>
<link>http://www.achievo.org</link>
<description>Achievo Nieuws RSS Feed</description>
<generator>ATK RSS Writer</generator>
<lastBuildDate>Tue, 31 Oct 2006 23:52:35 CET</lastBuildDate>
<item>
<title>Achievo 1.2.0 Released</title>
<link>http://www.achievo.org/download/releasenotes/1_2_0</link>
<description>Eerste nieuws item</description>
<pubDate>Mon, 24 Apr 2006 00:00:00 CEST</pubDate>
</item>
<item>
<title>Achievo 1.2.1 Released</title>
<link>http://www.achievo.org/download/releasenotes/1_2_1</link>
<description>Tweede nieuws item</description>
<pubDate>Mon, 29 May 2006 00:00:00 CEST</pubDate>
</item>
</channel>
</rss>
Zoals je ziet is het dus vrij eenvoudig om een eigen class te maken en daar ieder soort XML document mee te genereren.