Validierung mit RelaxNG und PHP 5 Dies ist ein Einstiegstutorial zur Validierung mit RelaxNG unter PHP 5. Erklärt werden wichtige RelaxNG Elemente und die Nutzung von RelaxNG mit PHP.
Relax NG (Regular Language For XML Next Generation) ist eine von OASIS weiterentwickelte Schemasprache zur Validierung von XML Daten. Wie auch das bekanntere XML-Schema ermöglicht Relax NG die Validierung sehr komplexer Datenstrukturen und Datentypen. Relax NG ist dabei nicht wirklich als Konkurrenz zum vom W3C entwickelten XML-Schema zu sehen, sondern vielmehr als anwendungszweckbezogene Alternative. Relax NG Definitionen zu W3C Formaten haben inzwischen sogar Einzug in offizielle Sheets des W3C gehalten. Hauptsächlich unterscheidet sich Relax NG von XML-Schema im einfacheren Vokabular und einigen zusätzlichen Validierungsregeln. Gemeinsamkeiten lassen sich in den Datentypen finden. Dort setzen beide Sprachen auf XML-Schema Datatypes.
Mit PHP 5 und dessen libxml2 Grundlage für XML Funktionalitäten, kann Relax NG jetzt auch zur Validierung unter PHP herangezogen werden.
Vom Idealfall ausgehend beginnen wir mit der Definition des XML Formats eines einfachen Warenkataloges.
<?xml version="1.0" encoding="UTF-8" ?>
<katalog>
<artikel nummer="1">
<preis>15.99</preis>
<name>RTFM Rockers - Best Of</name>
<kategorie>Musik</kategorie>
<media>CD</media>
</artikel>
<artikel nummer="2">
<name>Relax Gladiators - The Validator Tour</name>
<preis>9.99</preis>
<kategorie>Musik</kategorie>
<kategorie>Musik/Vinyl</kategorie>
<media>Vinyl</media>
<format>Single</format>
</artikel>
</katalog>
Ein mögliches Relax NG Schema zum obigen Beispiel.
<?xml version="1.0" encoding="UTF-8"?>
<element name="katalog"
xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<zeroOrMore>
<element name="artikel">
<interleave>
<element name="preis">
<text/>
</element>
<element name="name">
<text/>
</element>
<oneOrMore>
<element name="kategorie">
<text/>
</element>
</oneOrMore>
<element name="media">
<choice>
<value>CD</value>
<value>Vinyl</value>
</choice>
</element>
<optional>
<element name="format">
<text/>
</element>
</optional>
</interleave>
<attribute name="nummer">
<data type="int"/>
</attribute>
</element>
</zeroOrMore>
</element>
Dieser Artikel soll nur einen Einstieg in die Thematik bieten. Von daher sind in diesem Beipiel Relax NG Schema nur die wichtigsten Elemente aus Relax NG enthalten. Diese seien trotz der einfachen Lesbarkeit kurz erklärt.
"element" bezeichnet ein Element innerhalb eines XML Dokuments. Namespace und die zu verwendenen Datentypen können kurzerhand mit "xmlns" und "datatypeLibrary" mitgegeben werden. Das "name" Attribut bezeichnet wie zu erwarten den Namen des XML Elements. Im Beispiel unserer Root Node ist dies der Wert "katalog".
"zeroOrMore" bedeutet dass das Kindelement beliebig oft vorkommen und sogar fehlen darf. In unserem Beispiel bedeutet dies, dass beliebig viele Artikel im Katalog sein dürfen.
"oneOrMore" bedeutet dass das Kindelement mindestens einmal vorkommen muss. In unserem Beispiel bedeutet dies, dass es zu jedem Artikel mindestens eine Kategorie gehört.
"interleave" bedeutet dass die Kindelemente in beliegiger Reihenfolge vorkommen dürfen. Ist eine Gruppe von Elementen nicht in "interleave" eingeschlossen wird die Reihenfolge der Elemente strikt vorausgesetzt. Achtung: Eine Verhaltensvorschrift wie "interleave" ist in XML-Schema nicht vorhanden.
"attribute" bestimmt ein Attribute vom umschliessenden "element". Das Attribute "name" gibt dabei, korrespondierend zu "element", den Namen an.
"value" bestimmt den Wert des umschliessenden "attribute" bzw. "element".
"choice" zeigt eine Wahlmöglichkeit zwischen den Kindelementen an.
"data" bestimmt den Datentyp des umschliessenden RNG Elements. Die Nutzung der XML-Schema Datentypen vorausgesetzt finden Sie Infomationen zu diesem Punkt auf den W3C Webseiten.
"optional" kennzeichnet das optionale einmalige Vorhandensein der Kindelemente.
Um die XML Daten mit PHP 5 via Relax NG validieren zu können muss unser XML Beispiel Katalog zunächst in ein DOM Objekt "gewandelt" werden.
<?php
$dom = new DOMDocument();
$dom->load('katalog.xml');
?>
Mit "new DOMDocument()" wird eine neue Instanz eines DOM Objekts erzeugt und via DOMDocument::load() wird anschliessend unser XML Katalog eingelesen.
<?php
if ($dom->relaxNGValidate('katalog.rng')) echo ' :-) ';
else echo ' :-( ';
?>
Die DOM Methode "relaxNGValidate" erwartet als einziges Argument den Dateinamen unseres Relax NG Schemas und gibt im Erfolgsfall "true" zurück. Schlägt die Validierung fehl, wird entsprechend "false" zurückgegeben. Achtung: Schlägt die Validierung fehl wird zusätzlich ein "PHP Warning" mit Fehlerursache ausgegeben. Möchte man die Ausgabe unterdrücken bleibt nur der Weg das PHP Output Buffering anzuschalten:
<?php
ob_start();
$erfolg = $dom->relaxNGValidate('katalog.rng');
$fehler = ob_get_contents();
ob_end_clean();
if ($erfolg) echo ' :-) ';
else echo ' :-( ';
?>
Alternativ zur Methode "relaxNGValidate" kann auch "relaxNGValidateSource" verwendet werden, um anstatt gegen eine RNG Datei gegen einen RNG String zu validieren.
<?php
$xmldata = file_get_contents('katalog.rng');
if ($dom->relaxNGValidate($xmldata) echo ' :-) ';
else echo ' :-( ';
?>
Nachdem in diesem Einstiegstutorial bereits viele Möglichkeiten aufgezeigt wurden seien an dieser Stelle noch Grenzen genannt.
1.) Es ist derzeit nicht möglich mit RelaxNG die Häufigkeit von Elementvorkommen zu definieren, wie dies in XML-Schema möglich ist. Es sind lediglich die Angaben: "oneOrMore" und "zeroOrMore" möglich.
2.) Es gibt keine Unique Einschränkung. In unserem Beispielkatalog könnte es also mehrere Artikel mit gleicher Artikelnummer geben.
3.) Es ist in PHP derzeit nicht möglich eine Relax NG Datei als DOM Objekt gegen ein anderes DOM Objekt zu validieren. Möchte man viele Dateien gegen ein und den gleichen Relax NG Source validieren wird dieser jedes mal vor dem Validierungsvorgang neu gelesen und ausgewertet.
zurück
Internet Verweise zum Thema
Offizielle PHP Seite RelaxNG Homepage
|