XML, XSLT en PostgreSQL
Uit Yapf
PostgreSQL kan in samenwerking met libXML allerlei spannende dingen met XML doen. Niet alleen XML genereren, maar ook transformeren via XSLT.
Inhoud |
installatie
ubuntu: sudo -u postgres psql <databasename> -f /usr/share/postgresql/8.3/contrib/pgxml.sql
XML genereren
Hiervoor heeft PostgreSQL een handjevol functies. In feite zijn het gewoon stringfuncties (en dat is XML feitelijk ook) dus ze zijn bijzonder eenvoudig in het gebruik.
XMLELEMENT()
Dit genereert een XML element, een node als het ware. De parameters van deze functie zijn; een naam, een set attributen en een serie sub-elementen.
SELECT XMLELEMENT(name <elementnaam>); SELECT XMLELEMENT(name <elementnaam>, XMLATTRIBUTES(<expressie> AS <attribuutnaam>, ...)); SELECT XMLELEMENT(name <elementnaam>, XMLATTRIBUTES(<expressie> AS <attribuutnaam>, ...), XMLELEMENT(...));
XMLATTRIBUTES()
Deze functie genereert een setje attributen voor in een XMLELEMENT. De parameters zijn een serie expressie/name pairs in het formaat: <expressie> as <attribuutnaam>
SELECT
XMLELEMENT(name car,
XMLATTRIBUTES('52,192.56' AS price, 'Volvo' as brand),
XMLELEMENT(name engine,
XMLELEMENT(name fuel,
XMLATTRIBUTES('yes' as unleaded),
'petrol'
)
)
);
Uitkomst:
<car price="52,192.56" brand="Volvo"> <engine> <fuel>petrol</fuel> </engine> </car>
Alle waarden in dit voorbeeld kunnen ook velden uit een tabel zijn, of andere SQL expressies:
SELECT
XMLELEMENT(name student,
XMLATTRIBUTES(leeftijd,
geslacht,
studentnummer),
achternaam)
FROM
studenten;
uitvoer:
<student leeftijd="30" geslacht="m" studentnummer="119">Ho</student>" <student leeftijd="29" geslacht="v" studentnummer="96">Nas</student>" <student leeftijd="24" geslacht="v" studentnummer="97">Meermeisje</student>" <student leeftijd="35" geslacht="v" studentnummer="98">Jovis</student>" <student leeftijd="19" geslacht="m" studentnummer="99">Klungel</student>" <student leeftijd="24" geslacht="m" studentnummer="100">Adelaar</student>" <student leeftijd="22" geslacht="m" studentnummer="101">Lext</student>" <student leeftijd="25" geslacht="m" studentnummer="102">Vroegweg</student>" <student leeftijd="28" geslacht="m" studentnummer="103">de Laar</student>" ....etc....
XMLAGG()
Dit is een aggregaat dat meerdere elementen samenvoegt tot één XMLstring. Bovenstaande voorbeeld levert meerdere records op die je in PHP aan elkaar zou moeten plakken, XMLAGG() harkt ze in de query al bij elkaar en geeft één resultaat:
SELECT
XMLAGG(
XMLELEMENT(name student,
XMLATTRIBUTES(leeftijd,
geslacht,
studentnummer),
achternaam)
)
FROM
studenten;
En dat geeft dezelfde uitvoer als hierboven, maar dan als één record.
Dit alles kun je weer nesten in een XMLELEMENT:
SELECT
XMLELEMENT(name studenten,
XMLAGG(
XMLELEMENT(name student,
XMLATTRIBUTES(leeftijd,
geslacht,
studentnummer),
achternaam)
)
)
FROM
studenten
XSLT
Naast het genereren van XML kan PostgreSQL via LibXSLT ook XSLT transformaties uitvoeren via xslt_process(<xml>, <xslt>[, <parameter>=<value> [, ...]).
Het eerste argument is een XML document, het tweede is een geldige XSLTsheet, dus een complete sheet, geen fragment. De derde parameter is een serie parameters die aan de transformatie moeten worden doorgegeven.
SELECTXSLT_PROCESS('<schooldata><name>Zwijnstein</name></schooldata>',
'<?xml version="1.0"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://www.w3.org/1999/xhtml"><xsl:output method="html"/><xsl:template match="schooldata"><xsl:value-of select="name"/></xsl:template></xsl:stylesheet>')
De XML kan uiteraard uit een query komen:
SELECTXSLT_PROCESS(CAST((SELECT XMLELEMENT(name studenten, XMLAGG(XMLELEMENT(name student, XMLELEMENT(name achternaam,achternaam)))) FROM studenten) AS text),
'<?xml version="1.0"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://www.w3.org/1999/xhtml"><xsl:output method="html"/><xsl:template match="//student">Leerling: <xsl:value-of select="achternaam"/></xsl:template></xsl:stylesheet>')
En als je echt het avontuur in wil dan kan de XSLT ook uit een query komen.