Data importeren via XSLT
Uit Yapf
Via XSLT kun je ook prima XML data importeren. Daar zijn twee manieren voor; XML omzetten naar CSV data en dat importeren via de gebruikelijke methodes, of de XSLT parser toegang geven tot de PHP functies en de data direct verwerken.
Inhoud |
Testdata
De voorbeelden werken met deze testdata:
<?xml version="1.0" encoding="UTF-8"?> <data> <records> <record> <title>Sjakie en de slomeslagerfabriek.</title> <price>1435.45</price> </record> <record> <title>Bus gemist in 20 seconden.</title> <price>45.46</price> </record> </records> </data>
Omzetten naar CSV
Dit is de eenvoudigste manier die ook het minste werk kost, maar ook het minst flexibel is. Wat het doet is letterlijk een stuk CSV code genereren die je verrer kunt verwerken met PHP's fgetcsv(), MySQL's LOAD DATA INFILE, of PostgreSQL's COPY commando's. Simpel, doeltreffen, snel en saai.
De PHP parser
De XSLT parser is niets meer dan een instantie van XSLTProcessor, waaraan een XMLDocument en een XSLTDocument worden gevoerd. Dit is allemaal vrijwel direct uit de handleiding gekopierd dus kijk ook daar voor meer uitleg.
<?php $oXMLDocument = new DOMDocument(); $oXSLTDocument = new DOMDocument(); $oXSLTProcessor = new XSLTProcessor(); $oXMLDocument->load('xslt_import_data.xml', LIBXML_NOCDATA); $oXSLTDocument->load('xslt_import_xslt.xsl'); $oXSLTProcessor->importStylesheet($oXSLTDocument); echo $oXSLTProcessor->transformToXML($oXMLDocument); ?>
De XSLT sheet
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0' exclude-result-prefixes="xsl"> <xsl:output method="html" indent="yes" encoding="UTF-8" /> <!-- Begin het toepassen van de templates --> <xsl:template match="/"> <xsl:apply-templates select="//record" /> </xsl:template> <!-- Template voor een record --> <xsl:template match="record"> "<xsl:value-of select="title"/>","<xsl:value-of select="price"/>" </xsl:template> </xsl:stylesheet>
XSLT toegang geven tot PHP functies
Om je XSLT parser toegang te geven tot de PHP functies moet je een paar dingen doen.
- 1. registerphpfunctions aan te zetten op je parser.
- 2. IN je XSLT sheet aangeven dat de PHP namespace bestaat. Hiervoor volstaat iets als xmlns:php="http://php.net/xsl"
- 3. De functies definieren in PHP. Dit kunnen gewone procedurele functies zijn, of static methods in een class.
De parser
Dit is de parser zoals bij het CSV voorbeeld, maar met wat extra's.
Nieuw is de class fakeimporter die een method import bevat. Deze method neemt twee parameters en geeft een string terug waar die parameters in verwerkt zijn. Om data te importeren zou hier dus een functie staan die een query opbouwt en de data in de database spiest.
<?php class fakeimporter { public static function import($psText, $piPrice) { return sprintf('%s Tegen een prijs van: %8.2f', $psText, $piPrice); } } $oXMLDocument = new DOMDocument(); $oXSLTDocument = new DOMDocument(); $oXSLTProcessor = new XSLTProcessor(); $oXMLDocument->load('xslt_import_data.xml', LIBXML_NOCDATA); $oXSLTDocument->load('xslt_import_xslt.xsl'); $oXSLTProcessor->registerPHPFunctions(); $oXSLTProcessor->importStylesheet($oXSLTDocument); echo $oXSLTProcessor->transformToXML($oXMLDocument); ?>
XSLT Sheet
Dit is de sheet die de transformatie uitvoert. Noot dat hier bovenaan de PHP namespace is toegevoegd, zonder dat werkt het niet. Deze sheet levert HTML op om te laten zien wat er wordt gedaan, maar dat is verder puur bijzaak.
De werking van deze sheet is simpel; de hoofdtemplate zoekt in de XML naar alle data tags en roept de bijbehorende template daarop af. De template die daarbij hoort print een DIVje en vult die met de uitkomst van de PHP functie fakeimporter::import, en dat is dus de static method import van de fakeimporter class. Aan die method worden twee parameters meegegeven; de stringwaarde van het title veld van de record tag en de stringwaarde van het price veld. In de uitvoer komt te returnvalue van de method te staan en in dit geval is dat een funky berichtje.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0' exclude-result-prefixes="xsl" xmlns:php="http://php.net/xsl"> <xsl:output method="html" indent="yes" encoding="UTF-8" /> <!-- Begin het toepassen van de templates --> <xsl:template match="/"> <xsl:apply-templates select="//record" /> </xsl:template> <!-- Template voor een record --> <xsl:template match="record"> <div style="border: 1px solid black;padding:10px;margin:10px"> <strong>RECORD</strong> <p> <xsl:value-of select="php:function('fakeimporter::import', string(title), string(price))" /> </p> </div> </xsl:template> </xsl:stylesheet>