Een contentmanagementsysteem voor de faculteitsbibliotheek...
Transcript of Een contentmanagementsysteem voor de faculteitsbibliotheek...
Een contentmanagementsysteem voor de faculteitsbibliotheek
Davy Germeys
Promotor: prof. dr. ir. Erik D'Hollander
Begeleiders: prof. dr. ir. Koen De Bosschere, dr. ir. Michiel Ronsse, dr. Benny Malengier
Masterproef ingediend tot het behalen van de academische graad van Master in de toegepaste informatica
Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. Jan Van Campenhout Faculteit Ingenieurswetenschappen en Architectuur Academiejaar 2010-2011
Een contentmanagementsysteem voor de faculteitsbibliotheek
Davy Germeys
Promotor: prof. dr. ir. Erik D'Hollander
Begeleiders: prof. dr. ir. Koen De Bosschere, dr. ir. Michiel Ronsse, dr. Benny Malengier
Masterproef ingediend tot het behalen van de academische graad van Master in de toegepaste informatica
Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. Jan Van Campenhout Faculteit Ingenieurswetenschappen en Architectuur Academiejaar 2010-2011
Dankwoord
Dit werk dat U nu inkijkt had ik niet alleen tot stand kunnen brengen. Ik wil dan ook iedereen
die rechtstreeks en onrechtstreeks mij bij het realiseren van deze masterproef geholpen heeft,
bedanken.
In de eerste plaats mijn promotor, prof. dr. ir. Erik D'Hollander voor zijn begeleiding, hulp en
steun. Verder alle lesgevers en assistenten die mij in 1 jaar tijd in de MTI opleiding de nodige
kennis en vaardigheden hebben bijgebracht zodat dit werk mogelijk werd.
Ten slotte wil ik ook mijn familie bedanken voor de steun die ik van hen ontvangen heb.
Davy Germeys
De toelating tot bruikleen "De auteur geeft de toelating deze masterproef voor consultatie beschikbaar te stellen en delen van de masterproef te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit deze masterproef." "The author gives permission to make this master dissertation available for consultation and to copy parts of this master dissertation for personal use. In the case of any other use, the limitations of the copyright have to be respected, in particular with regard to the obligation to state expressly the source when quoting results from this master dissertation."
11 augustus 2011 Davy Germeys
Inhoud 1. Inleiding ........................................................................................................................................... 1
2. Het huidige bibliotheeksysteem ...................................................................................................... 2
3. XML en Symphony cms.................................................................................................................... 4
3.1 XML .......................................................................................................................................... 4
3.2 Symphony CMS ........................................................................................................................ 8
4. XSLT met behulp van PHP .............................................................................................................. 12
4.1 Structuur van de site ............................................................................................................. 12
4.2 PHP en XSLT ........................................................................................................................... 13
4.3 Zoeken op vakken en referentiewerken ............................................................................... 15
4.4 Details van vakken en referentiewerken............................................................................... 19
5. Besluit ............................................................................................................................................ 21
Bijlagen .................................................................................................................................................. 22
Bijlage A: XML webdata voorbeeld ................................................................................................... 22
Bijlage B: Systeem ............................................................................................................................. 23
Bijlage C: Een voudige stylesheet om een vak op lesgever te zoeken .............................................. 24
Bijlage D: Code van de vakzoekfunctie - zoek.php ............................................................................ 25
Bijlage E: Code van de Referentiewerkzoekfunctie - zoekRef.php ................................................... 35
Bijlage F: Code van de vakdetailpagina - Detail.php ......................................................................... 44
Bijlage G: Code van de referentiewerkdetails detailRef.php ............................................................ 51
Referenties ............................................................................................................................................ 58
Lijst van figuren Figuur 1 Webdata tabel uit Access .......................................................................................................... 5
Figuur 2 Resultaat XML exportering van de eerste record uit figuur 1. Kleuren en positionering
verduidelijken de syntax. ........................................................................................................................ 6
Figuur 3: Een eenvoudige Symphony page template ............................................................................ 10
Figuur 4: Output van eenvoudige Symphony page template ............................................................... 10
Figuur 5: Websitestructuur van het zoeksysteem en interactie tussen de pagina's ............................ 13
Figuur 6: XSLTProcessor voorbeeld code .............................................................................................. 14
1
1. Inleiding
De faculteitsbibliotheek heeft een site waarmee gegevens over de vakken en de aanwezigheid
van hun cursussen kunnen worden opgezocht. Deze site maakt gebruik van een Access
Databank, ISS en ASP. Hierdoor is de site sterk afhankelijk van een Windows Server.
Bovendien is een uitbreiding van de functionaliteit gewenst. Zo moeten er ook gegevens van
referentiewerken via de site beschikbaar worden.
De ontwikkelde oplossing hiervoor bestaat uit een combinatie van XML en XSLT. De data in
de XML standaard opslaan heeft als voordeel dat ISS en de Access databank geen
beperkingen aan de server meer opleggen. XSLT is een standaard voor de transformatie van
XML data. Hiermee kan de data op de site aan de gebruikers aangeboden worden.
Om het beheer van de site te stroomlijnen, wordt de implementatie van het
contentmanagementsysteem Symphony CMS overwogen en onderzocht.
Hoofdstuk 2 zal de huidige site beschrijven, de beperkingen daarvan verduidelijken en de
vereisten van de nieuwe site vastleggen. Hoofdstuk 3 behandelt eerst XML als oplossing.
Daarna wordt ook de implementatie van een contentmanagementsysteem besproken en
overwogen. Hoofdstuk 4 gaat dieper in op de oplossing en haar deelaspecten. Ook XSLT
wordt in hoofdstuk 4 behandeld.
2
2. Het huidige bibliotheeksysteem
De faculteitsbibliotheek heeft een online cursusbibliotheek waarin de cursussen opgezocht
kunnen worden. Van die cursussen kan men dan de details omtrent het vak en de ECTS-fiche
raadplegen. De gegevens van de online cursusbibliotheek komen uit de cursusdatabank. De
input van deze cursusdatabank, d.w.z. cursussen, lesgevers, opleidingen en studiefiche-
informatie wordt geleverd door het beheersysteem Oasis.
Uit de studiefiches wordt een tabel met referentiewerken opgesteld. Deze referentiewerken
worden systematisch aangekocht en in de faculteitsbibliotheek geplaatst.
De tabel met referentiewerken geeft ook weer welke vakken welke referentiewerken
gebruiken. Deze extra informatie is momenteel nog niet via de website beschikbaar. Dit via
een view op de website eenvoudig raadpleegbaar maken, is dan ook een gewenste uitbreiding
van de huidige functionaliteit. Zo zou voor elk vak duidelijk moeten zijn welke
referentiewerken het gebruikt. Maar naast de vakken moet er ook op referentiewerken gezocht
kunnen worden en moet bij elk referentiewerk duidelijk zijn voor welke vakken dat
referentiewerk gebruikt wordt.
De gegevens van de vakken bevinden zich in de Microsoft Access cursusdatabank. Deze vak-
en cursusgegevens in de databank moeten via de website doorzoek- en representeerbaar zijn.
Hiervoor wordt in de huidige omgeving gebruik gemaakt van Internet Information
Services(IIS) en Active Server Pages(ASP).
De Microsoft Access databank heeft als voordeel dat de interne gebruikers een redelijk
eenvoudig te gebruiken, eenvoudig aan te passen en al jaren bekende databank voorgeschoteld
krijgen. Het voorbije decennium is de databank zelf steeds verder uitgebreid met extra
tabellen, queries en rapporten. Hierdoor is de Access databank dan ook steeds groter en
complexer geworden.1 Maar omdat de bibliotheekwebsite zelf via de IIS van deze Access
databank afhankelijk is, is een eventuele aanpassing of vervanging van de website alleen
mogelijk indien er ook hiervoor een oplossing is. Het gebruik van de IIS heeft ook tot gevolg
dat men van Microsoft servers afhankelijk is, waardoor aanpassingen of vernieuwingen met
iets anders dan Windows niet vanzelfsprekend zijn.
1 Zo werkten sommige rapporten niet meer omdat de query waarvan ze afhankelijk zijn, niet meer bestaat.
Bovendien is het .mdb Access bestand 35MB groot, terwijl de alle data zelf in een net geen 7MB .mdb bestand
passen.
3
Bovendien komen in de huidige databank meerdere records voor hetzelfde vak voor. Dit is zo
omdat voor sommige attributen van een vak, zoals onder andere „lesgever‟ of „studiejaar‟ er
meerdere waarden kunnen voorkomen. Voor elke mogelijke combinatie is er een aparte
record voorzien. Dit zorgt er voor dat indien er bij een vak bijvoorbeeld 2 lesgevers elk aan
drie verschillende jaren hetzelfde vak geven, je al direct 6 records hebt. Het huidige systeem
geeft ongefilterd alle combinaties van eenzelfde vak met verschillende lesgevers en
opleidingen als aparte records weer. Dit geeft 2965 records voor de 696 vakken (2010-2011).
De records kunnen wel gefilterd worden per opleiding, studiejaar etc...
De website zelf maakt gebruik van de server-side scripting Windows ASP technologie. Deze
wordt het best op Windows servers ondersteund, wat nog meer bijdraagt tot de Windows
afhankelijkheid. De ASP is ook de oude „classic ASP‟ en niet haar opvolger ASP.NET van
januari 2002. De in VBScript geïmplementeerde functionaliteit is verspreid over 35 ASP
codebestanden. Er is echter geen documentatie beschikbaar voor deze vrij complexe code. Het
is dan ook niet eenvoudig te doorgronden welke stukken code nog wel en welke niet meer
gebruikt worden. Daardoor is het onderhoud van de website niet eenvoudig.
In de toekomst kan het ook wenselijk zijn de up-to-date data rechtstreeks uit het nieuwe
Oasis-platform te halen, maar met de Windows implementatie ligt dat vrij moeilijk. Oasis
maakt van Oracle databanktechnologie gebruik [1].Om deze data voor de site beschikbaar te
maken, zou ze via de Access databank aangeboden moeten worden. De realisatie hiervan is
niet onmogelijk maar vrij complex en zorgt ervoor dat de Access en Windows
afhankelijkheden niet geremedieerd worden, maar versterkt.
De combinatie van de MS Access databank, het MS IIS en de VBScript ASP programmatie
creëren een sterke platformafhankelijkheid. Hierdoor is er geen flexibiliteit bij de
serverinfrastructuur mogelijk. Het onderhoud van de website zelf is ook erg complex zodat
een versterking van de aangeboden functionaliteit met een view op de referentiewerken niet
eenvoudig toe te voegen is. Een oplossing van deze problemen dringt zich dan ook op.
Een nieuw systeem dat dit oude zal vervangen moet dan ook aan meerdere eisen voldoen. Zo
moet het mogelijk zijn om de gegevens van de oude Access databank te gebruiken zonder dat
er op de server zelf Access of IIS ondersteund moeten worden. Op die manier kan het
bibliotheekpersoneel de vertrouwde Access werkomgeving blijven gebruiken. Maar het
systeem op de server mag niet meer afhankelijk zijn van Access en IIS. Zo zal dit systeem dan
niet langer specifieke eisen aan de serverinfrastructuur stellen en meer platformonafhankelijk
4
worden. De nieuwe functionaliteit die de informatie omtrent de referentiewerken wel
beschikbaar stelt, moet natuurlijk ook in het nieuwe systeem geïmplementeerd worden. Het
probleem waarbij één vak als meerdere records weergegeven wordt, kan in de nieuwe site best
ook verholpen worden. Verder is het wenselijk dat er aan de nieuwe bibliotheektoepassing
eenvoudig nieuwe data aangeboden kan worden, bij voorkeur zonder dat dit noodzakelijk via
de Access databank moet. Zo kan het systeem importvriendelijker worden voor gegevens van
andere databanken.
3. XML en Symphony cms
3.1 XML Uit het vorige hoofdstuk blijkt dat de oude Access databank o.m. voor een ongewenste
afhankelijkheid van IIS zorgt. Voor het website-systeem zelf moet hier dan ook een oplossing
worden voorzien. De databank vervangen door een ander systeem lijkt misschien
vanzelfsprekend. Dit sluit echter uit dat de gebruikers hun vertrouwde databank intern nog
kunnen gebruiken. Bovendien wordt men bij een nieuw databanksysteem afhankelijk van de
nieuwe databank wat het probleem van de platformafhankelijkheid alleen zou verplaatsen.
Idealiter zou de website zelf niet meer rechtstreeks van één of ander specifieke, Access of
andere, databank afhankelijk zijn.
De gekozen oplossing maakt van XML gebruik. Kort samengevat haalt het websitesysteem de
benodigde gegevens uit XML bestanden. De gegevens zitten in die bestanden volgens de
XML standaard opgeslagen.
Extensible Markup Language (XML) is een standaard van het World Wide Web Consortium
die al van aan het begin bedoeld was om voor het internet gebruikt te kunnen worden. “XML
has been designed for ease of implementation and for interoperability with both SGML and
HTML.”[2] XML is dan ook een “…extremely simple dialect of SGML …”[3] , of anders
gezegd een eenvoudiger en makkelijker te gebruiken variant van het complexere SGML. Dit
SGML, voluit Standard Generalized Markup Language, is zelf een ISO standaard
technologie.[4]
XML is dus een algemene standaard en de technologie is niet het eigendom van één specifiek
bedrijf. Daarom zal het gebruik van XML in plaats van de Microsoft Access databank en de
gerelateerde IIS, bijdragen tot de realisatie van een platformonafhankelijker systeem. XML
5
wordt breed aanvaard en ondersteund. Zo is het mogelijk om de data uit de Access databank
via MS Access eenvoudig naar bestanden in het XML formaat te exporteren. De gegevens in
de databank veranderen niet vaak omdat vakken normaal alleen bij een nieuw academiejaar
kunnen wijzigen. Daarom is alleen een periodieke in dit geval jaarlijkse exportering van
gegevens uit de databank nodig. Het hanteren van de XML standaard maakt het bovendien
ook mogelijk om gegevens die van elders komen, te hanteren. Op deze wijze biedt dit ook
voor eventueel toekomstige databronnen een oplossing.
In een XML document kunnen gegevens gestructureerd weergegeven worden. Dit wordt hier
met behulp van een voorbeeld uit de databank aangetoond. Figuur 1 toont de webdata tabel
van de Access databank in de design mode. Hier kan je duidelijk zien hoe de gegevens in een
traditionele relationele databank gestructureerd zijn in meerdere records. De webdata tabel
werd uit meerdere tabellen samengesteld om gegevens die de website nodig heeft, aan te
bieden.
Figuur 1 Webdata tabel uit Access
In figuur 2 is het exporteringsresultaat van het eerste record2 van figuur 1 te vinden. De eerste
regel is de XML declaratie. Deze maakt duidelijk dat dit document voldoet aan XML versie
1.0 en de tekens in UTF-8 gecodeerd zijn. Daarna komt het buitenste element, “dataroot” dat
als een verpakking om alle data heen zit. Attributen geven extra informatie over hun element.
2 Een uitgebreider voorbeeld met meer records zou hier te veel plaats innemen. Een uitgebreider voorbeeld
met de volledige exportering van 4 records kan integraal in bijlage A gevonden worden.
6
De attributen die hier binnen de dataroot tag zitten, zijn bij de exportering door Access zo
gekozen. Al deze attributen zijn hier niet verplicht om correcte XML te hebben, alleen de
aanwezigheid van een dataroot element is altijd noodzakelijk.3
Indien meerdere elementen dezelfde naam hebben, maar een verschillende betekenis, ontstaat
er een conflict. Dit kan opgelost worden door voor elke verschillende betekenis aan de namen
een prefix toe te voegen zodat de namen toch verschillend zijn. Stel bijvoorbeeld dat
“webdata” niet alleen gegevens over vakken zou bevatten, maar ook gegevens over
faculteiten. Dan is er een conflict. Binnen de afbakening van een “webdata” tag is men dan
niet meer zeker over de inhoud en hoe je dit dient te interpreteren. Met prefixen kan dit
verholpen worden. Zo kan met “vak:webdata” en “faculteit:webdata” in plaats van “webdata”
de onduidelijkheid wegnemen. Indien je zulke prefixen gebruikt, ben je verplicht om
namespaces te definiëren voor elke gehanteerde prefix. Het “xmlns” attribuut definieert deze
namespace. In het voorbeeld kan dit dan voor de eerste tag xmlns:vak=”URI” zijn. URI moet
alleen een unieke naam zijn, maar vaak wordt een relevante url gehanteerd. Merk op dat in het
voorbeeld van figuur 2 er eigenlijk geen prefix tags gehanteerd worden en dat xlms attributen
dus overbodig zijn.
Figuur 2 Resultaat XML exportering van de eerste record uit figuur 1. Kleuren en positionering verduidelijken de syntax.
3 Merk op dat het dataroot element niet perse “dataroot” als naam moet hebben. Elke andere naam zou ook
correcte XML opleveren. Het hiërarchisch hoogste element wordt vaak wel de dataroot genoemd. Het deze naam geven maakt verwijzen naar elementen binnen de hiërarchie dan ook iets gemakkelijker.
7
Het laatste attribuut binnen de dataroot tag is generated. Dat geeft weer wanneer het XML
document aangemaakt is. Ook dat attribuut is niet verplicht.
In XML worden gegevens met behulp van elementen en attributen gestructureerd. Elementen
kunnen in andere elementen genest worden om zo een hiërarchische boomstructuur te
bekomen. FTWafkorting, Vak, NT, … bevinden zich allemaal in het webdata element. Dit is
dan ook hun „parent‟.
Elk element onder het dataroot element wordt een knoop genoemd. In het voorbeeld van
figuur 2 kan je bijvoorbeeld webdata en NR knopen (nodes) noemen. In het beperkte
voorbeeld waar er slechts één vak in verwerkt is, is dat vrij zinloos. In de wat ruimere bijlage
A daarentegen komt het webdata element al 4 keer voor en kan je van vier knopen spreken.
Dit is wel betekenisvol omdat elke knoop hier één vak vertegenwoordigd. De webdata knopen
zijn gelijkaardig aan de records uit de Access databank. Maar in tegenstelling tot de Access
databank, laat XML veel vrijheid in de wijze waarop de gegevens gestructureerd worden. Er
kunnen in één document verscheidene soorten data geplaatst worden terwijl dat in Access in
meerdere tabellen zou moeten gerealiseerd worden.
Sommige aspecten van XML zijn enigszins gelijkaardig aan HTML. Dat komt omdat HTML
vanaf zijn ontstaan door SGML beïnvloed is.[5] Merk wel op dat men in XML de syntax
strict dient te volgen.[6] In HTML zou dat in principe ook moeten, alhoewel een fout daar
meestal minder problematisch is omdat de browser vaak wel met syntaxfouten kan omgaan.
Bij XML daarentegen is een fout al snel fataal. De belangrijkste syntaxregels worden hier
vermeld.[6] Ten eerste moeten waarden van attributen die binnenin een tag staan, altijd tussen
aanhalingstekens staan. Bovendien moet een geopende tag ook altijd weer gesloten worden.
Ten derde moeten tags juist genest worden. Dat betekent dat als een tag binnenin een andere
tag geopend wordt, die tag ook binnen die tag gesloten moet worden.4 XML is ook
hoofdlettergevoelig; begin en eindtag moeten dan ook exact op dezelfde manier geschreven
zijn. De laatste verplichting is dat alle elementen in een XML document een rootelement
moeten hebben. Dat betekent dat alle elementen in een buitenste element verpakt moeten zijn,
behalve dat ene buitenste element.
Ten slotte zijn er binnen XML ook een aantal tekens die een specifieke betekenis hebben. Dit
zijn <, >, &, „ en “ (kleiner dan, groter dan, ampersand, apostrof en de dubbele quote). Men
4 “<i><b>voorbeeld</b></i>” of “<b><i>voorbeeld</i></b>” is de juiste syntax, maar de tags door elkaar
gebruiken kan niet.
8
moet altijd voorzichtig zijn met deze karakters omdat ze onbedoeld de syntax van het XML
document kunnen veranderen en verstoren. Merk op dat: “Only the characters "<" and "&" are
strictly illegal in XML.”[6] Toch zijn al deze karakters gevaarlijk. Indien ze in een XML
document kunnen voorkomen, moet er een oplossing voor worden voorzien.
In XML is de data gestructureerd opgeslagen. De gebruiker van de site moet echter de data
kunnen bekijken op een manier zodat er in de data op attributen gezocht en geselecteerd kan
worden. De knopen die dan aangeboden worden, moeten dan ook nog een layout meekrijgen.
Met behulp van XSL stylesheets voor XML en XSLT transformaties wordt de XML naar
HTML getransformeerd. De layout van deze HTML zal dan via CSS verzorgd worden. XSLT
en XSL komen in hoofdstuk 4 uitgebreid aan bod.
3.2 Symphony CMS De term contentmanagementsysteem (CMS) wordt sterk met websites geassocieerd. Het
begrip heeft evenwel een veel ruimere betekenis. Zoals de naam laat vermoeden gaat het over
het systematisch beheer van gegevens. Zo is er ook ECM, Enterprise Content Management.
Hier wordt alleen de webvariant5 besproken. “WCM”, web content management, “is about
managing the publishing and distribution of information.”[7] De verwachtingen die aan goede
contentmanagementsystemen gesteld worden, gaan verder dan dat. Gebruiksvriendelijkheid
voor leken is een kernvereiste geworden. “A CMS should be able to allow a non-technical
user to manage any asset on a Web site that they wish to interact with, whether that is a piece
of content, a picture, a video or information that is pulled from other sources.”[7] Samengevat
kan er gesteld worden dat een contentmanagementsysteem dus ervoor moet zorgen dat de
gebruikers gemakkelijk alle aspecten van de website kunnen beheren.
Voor de site van de faculteitsbibliotheek werd al snel het gebruik van een
contentmanagementsysteem overwogen. Dit moet er dan voor zorgen dat het toekomstig
onderhoud van de site eenvoudig kan plaatsvinden zonder dat hiervoor veel technische kennis
vereist is. Er werd aanvankelijk voor Symphony gekozen omdat dat op XML en XSLT
gebaseerd is. Aangezien de data in XML formaat aangeleverd wordt, is Symphony een
logische keuze als cms.
5 Vanaf hier zal het alleen nog maar over de webvariant gaan. Voor de rest van dit hoofdstuk is dus CMS
equivalent met WCM.
9
Symphony is een open source content management systeem. Symphony is in PHP
geschreven. Voor de XML documenten en XSLT operaties maakt het gebruik van de PHP
libXML module met de XSLT extensie.[8] Symphony werkt met meerdere configureerbare
lagen. De Sections zijn algemene elementen waarmee het inhoudstype van een geheel project
gedefinieerd kan worden. Pages tonen de gewenste inhoud aan de gebruiker. Aan de pages
zelf wordt met behulp van de page templates vorm gegeven. Deze page templates zijn XSLT
stylesheets die gebruikt worden voor XSLT transformaties. Data sources leveren de inhoud
waaraan in de pages door de page templates vorm wordt gegeven.[9] Een data source moet
gegevens in xml formaat aangereikt krijgen.
Door deze combinatie is Symphony heel geschikt om gegevens in XML formaat te hanteren.
Zo kan men bijvoorbeeld vrij eenvoudig RSS feeds of een weerbericht dat in XML formaat
aangereikt wordt, via XSLT transformaties op de site aanbieden. Symphony zal de voor data
sources aangereikte gegevens zelf ophalen, filteren, sorteren en opnieuw naar XML formaat
herwerken om het dan binnen Symphony als data source beschikbaar te stellen.[10] Wanneer
er echter een grote hoeveelheid XML data aangeleverd wordt, kunnen de wachttijden te lang
worden. Dit is zeker voor de vakgegevens die naar webdata.xml geëxporteerd zijn, een
probleem. Dat document is 47159 lijnen lang en heeft als resultaat dat Symphony zo sterk
vertraagt wordt zodat er time-outs ontstaan. Deze bewering wordt gestaafd met volgend
experiment.6
Voor dit experiment werd de volledige webdata.xml in Symphony als een “Custom XML-
Static XML” data source aangeboden. Daarna werd een nieuwe page aangemaakt die deze
data source als gegevensbron had. Dan werden via Symphonys eigen debug mode de voor die
pagina beschikbare XML gegevens, bekeken. Het weergeven hiervan leidde echter tot een
PHP time-out omdat het script hiervoor meer dan 30 seconden nodig had. De time-out naar 2
minuten verhogen, leidde dan weer tot een overschrijding van de PHP geheugenbegrenzing
die op 16MB stond en ook 32MB en 64MB bleken onvoldoende. Zelfs 128MB en 5 minuten
bleek nog te weinig tijd te zijn. Symphonys debug functionaliteit kan dus niet omgaan met de
webdata als data source.
Bij een redelijk grote hoeveelheid XML data is de overhead die de Symphony data sources
genereert al substantieel. Dit neemt niet weg dat Symphony geschikt is om XML data te
hanteren bij een website, maar alleen in beperkte hoeveelheden.
6 Zie bijlage B voor informatie omtrent de configuratie die hierbij gebruikt werd.
10
De page templates die aan pagina‟s vorm geven, zijn XSLT stylesheets. XSL, Extensible
Stylesheet Language, omvat een familie van aanbevelingen voor de transformatie en
representatie van XML documenten.[11] XSLT staat voor XSL Transformations en is een
onderdeel van deze familie. De andere 2 aanbevelingen van deze familie zijn XPath(XML
Path language) en XSL-FO(XSL Formatting Objects). XPath is een taal om delen van een
XML document te kunnen adresseren.[12] XSL en XSLT worden soms verward, maar zijn
dus toch niet hetzelfde.[13] De verwarring wordt nog versterkt doordat in XSLT documenten
xsl als prefix gebruikt wordt.
Omdat Symphony van libXML gebruik maakt, is het beperkt tot XSLT 1.0 en aldus kunnen
de uitgebreidere mogelijkheden XSLT 2.0 niet gebruikt worden. Met XSLT 1.0 kan ook
vrijwel alles gerealiseerd worden, maar soms vereist dat lange en ingewikkelde oplossingen.
Een vrij eenvoudige statische pagina kan met een kort XSL document gerealiseerd worden.
Indien men bijvoorbeeld de gegevens van één gekozen vak wil weergeven, kan daar een korte
template voor geschreven worden. Een voorbeeld hiervan is weergegeven in de figuur 3 en de
op basis hiervan gegenereerde pagina in figuur 4.
Figuur 3: Een eenvoudige Symphony page template
Figuur 4: Output van eenvoudige Symphony page template
11
Op de site moeten de pages echter sterk dynamisch zijn. Het is de bedoeling dat de gebruiker
de vakken en referentiewerken op meerdere manieren kan zoeken en bekijken. Dit is niet
eenvoudig te realiseren met een statische XSLT template. XSLT kan hiermee omgaan of door
met testen een beslissingsboom op te zetten, of door voor elk geval een aparte template te
gebruiken. De te verkiezen methode is het gebruiken van meerdere templates.[14] Dan wordt
er voor elk mogelijk geval een aparte template geschreven. Dit is problematisch omdat er
voor de site veel mogelijke gevallen zijn. Zo kan je bijvoorbeeld de vakken op vraag van de
gebruiker sorteren op NR, naam, lesgever, vakgroep, studiejaar en of de cursus in de
bibliotheek aanwezig is. Dit alleen geeft 7 variaties die strikt genomen elk een eigen template
moeten krijgen. Natuurlijk kan je in twee richtingen sorteren (oplopend en aflopend). Dat
geeft dan 14 =7*2 mogelijkheden en als je alle mogelijke zoekopdrachten daar aan toevoegt,
wordt dat nog een veelvoud. Alleen met XSLT page templates werken is dus niet
vanzelfsprekend. De minder orthodoxe beslissingsboom is ook geen goede oplossing omdat
dit tot een zeer complexe stylesheet zou leiden.
De geselecteerde knopen moeten ook gesorteerd worden. Dat gebeurt via een xsl:sort
statement. Hierin moet ingevuld worden waarop gesorteerd wordt, en in welke richting. Het
moeilijke hieraan is, dat de eerste keer dat men op een keuze in het hoofd van een kolom klikt
er oplopend moet gesorteerd worden. Bij een tweede klik aflopend en bij verdere klikken
dient dat telkens weer om te wisselen. Indien er gevraagd wordt op een ander attribuut te
sorteren, moet het dan ook direct oplopend zijn (wat dus een reset inhoud alsof het een eerste
klik is). Als er nog geen sorteeroptie gevraagd is, moet er een standaardsortering gehanteerd
worden. Eenvoudigweg een Symphony parameter invullen is hier dus niet voldoende. Bij iets
zo schijnbaar simpel als sorteren wordt duidelijk waarom de huidige site zoveel ingewikkelde
code heeft en alleen XSLT gebruiken niet haalbaar is.
Merk op dat een XSLT instructie stylesheet zelf ook een correct XML document moet zijn. Al
de regels omtrent XML syntax gelden dan dus ook voor XSLT. De speciale karakters die in
paragraaf 3.1 vermeld werden, kunnen problemen veroorzaken. Alhoewel Symphony zelf
voor een aantal karakters oplossingen voorziet, zal bijvoorbeeld een zoekopdracht waarin een
„ç‟, „é‟ of „è‟ voorkomt het systeem doen falen.7 De aangewezen methode om dit op te lossen,
is dan ook deze karakters buiten XSLT op de vangen. Die opvang kan met behulp van PHP
gerealiseerd worden.
7 Een XSLT Stylesheet die dit illustreert, vindt u in bijlage C.
12
Verder heeft Symphony een vrij steile leercurve en is daarom niet eenvoudig te gebruiken.
Symphony is bovendien nog vrij recent. Een ongelukkig gevolg hiervan is dat de
documentatie meestal te beperkt is. “Documentation has never been Symphony's strong
point.” [15] Dit is niet in overeenstemming met de CMS doelstelling om het websitebeheer
eenvoudig te maken. Dit vertraagt het ontwikkelen met en gebruik van Symphony voor niet
triviale toepassingen.
Als gevolg van deze specifieke problemen werd besloten om de website niet met behulp van
Symphony te realiseren. De idee om data in XML formaat via XSLT transformaties te
formatteren zal wel gebruikt worden. Maar om de problemen met de vele benodigde
templates voor alle variaties op te lossen, werd besloten een combinatie van PHP en XSLT te
gebruiken. Het volgende hoofdstuk zal uitgebreid verduidelijken hoe dit gerealiseerd is.
4. XSLT met behulp van PHP
4.1 Structuur van de site Op de site moet er op vakken en referentiewerken gezocht kunnen worden. Vanaf de
vakzoekpagina moet dan voor een gekozen vak een detailpagina opgeroepen kunnen worden.
Die detailpagina bevat dan de vakgegevens, de ECTS-fiche en de bij dat vak gebruikte
referentiewerken. Ook voor de referentiewerken is er een zoekpagina waarvan er naar een
detailpagina van een referentiewerk gegaan kan worden.
Vanaf de detailpagina van een vak kan ook naar de detailpagina van elk van de gebruikte
referentiewerken gegaan worden. En op de detailpagina van een referentiewerk wordt
vermeld voor welke vakken dit gebruikt wordt met links naar de desbetreffende vakken.8
Wanneer één van de twee detailpagina‟s aangesproken wordt, moet er meegegeven worden
van welk vak of referentiewerk dit de detailpagina moet zijn. Voor een vak gebeurt dat met
behulp van de vakcode (NR in webdata.xml), bijvoorbeeld „E082700‟ voor het vak
Architectuurgeschiedenis 2. Voor een referentiewerk wordt een referentiewerknummer
(RefNr) gehanteerd. Dat NR of RefNr wordt via de URL als parameter aan de detailpagina
aangereikt. Zo kan men bovendien rechtstreeks met behulp van NR of RefNr de gegevens van
8 Merk op dat niet aan elk vak referentiewerken gekoppeld zijn en dat niet aan elk referentiewerk een vak
gekoppeld is. De lijst van referentiewerken of vakken zal in die gevallen geen elementen bevatten.
13
een vak of referentiewerk opvragen. Ook de zoekpagina‟s maken gebruik van URL
parameters om de zoekopdracht te ontvangen.
Het gehele systeem bestaat dus uit 4 delen. Deze vier delen krijgen elk een eigen pagina. Elk
van deze worden met een eigen PHP pagina gerealiseerd. Zo zoek je vakken op „zoek.php‟,
referentiewerken op „zoekRef.php‟ en staan de details van vakken op „detail.php‟ en de details
van referentiewerken op „detailRef.php‟. Op die manier wordt het systeem in 4 onafhankelijke
modules gerealiseerd. Op die manier is het eenvoudiger om één pagina aan te passen.
Figuur 5 toont de structuur met de vier pagina‟s en hoe er tussen deze pagina‟s doorverwezen
wordt om details van een vak (detail.php) of referentiewerk (detailRef.php) weer te geven. Bij
de pijlen staat wat via de URL parameters meegegeven wordt om zo het juiste vak of
referentiewerk weer te kunnen geven.
Figuur 5: Websitestructuur van het zoeksysteem en interactie tussen de pagina's
4.2 PHP en XSLT De XSL Transformaties worden met een PHP XSLTProcessor[16] gerealiseerd. Deze is
onderdeel van de XSL extensie die standaard in PHP 5 ingegrepen is.[17] De XSL extensie
zelf is dan weer afhankelijk van de libXML extensie.[18] Algemeen gesteld zijn de eisen die
de site aan PHP stelt dus hetzelfde als van Symphony, met dat verschil dat er geen databank
nodig is. MySQL is dus niet noodzakelijk voor de site.
De manier waarop de XSLTProcessor gebruikt wordt, is gebaseerd op de voorbeelden uit de
PHP handleiding.[19][20] Figuur 6 geeft de code die hiervoor nodig is weer.
14
Figuur 6: XSLTProcessor voorbeeld code
Eerst wordt er een XSLTProcessor $processor aangemaakt. Die processor zal voor een XSL
Transformatie twee zaken nodig hebben: Instructies in de vorm van een XSLT stylsheet9 en
de XML data die getransformeerd worden.
De XSLT instructies worden als de string $xsl aangereikt en in een SimpleXMLElement
verpakt. Dit kan dan bij de processor als stylesheet ingeladen worden. De XML data bevindt
zich in een extern bestand webdata.xml in de xml map. Een DOMDocument wordt
aangemaakt als $xmldocument en de XML data worden ingeladen. Voor de processor wordt
de methode transformToXML aangeroepen en deze methode krijgt het xmldocument mee. 10
Het resultaat van de XSL Transformatie wordt dan via het echo commando als output in de
HTML pagina ingevoegd.
Dit betekend dat de XSLT instructies dus via de string $xsl aangereikt worden. Die string
wordt in PHP gecreëerd als een heredoc. De xsl is niet statisch maar variabel en wordt aan de
gebruikersinput aangepast. In deze XSLT string staan er meerdere PHP variabelen die nog
moeten worden ingevuld. Dat gebeurt op basis van via de URL doorgegeven
parameters.(GET) Deze werkwijze wordt op de 4 pagina‟s gehanteerd, maar wel met telkens
enige aanpassingen. De werking van de pagina‟s wordt in de volgende paragrafen verder
geduid.
9 Merk op dat de XSLT stylesheet hier verder en in de code $xsl noemt. Alhoewel XSL en XSLT strikt niet
hetzelfde zijn, worden ze vaak verward. Ook in de voorbeelden van de PHP handleiding wordt XSL als synoniem voor XSLT gebruikt.[19][20] De instructies zijn dus XSL, de data XML. 10
SimpleXMLElement kan XML data via een string ontvangen, een DOMDocument kan dat niet. TransformToXML() moet een DOMdocument meekrijgen. Dit verklaart waarom de XSL instructies in een SimpleXMLElement geplaatst wordt en de XML in een DOMDocument.
15
4.3 Zoeken op vakken en referentiewerken De implementatie van het zoeken naar vakken en referentiewerken is erg gelijkaardig. Hier
wordt vooral de zoekfunctie naar vakken (in zoek.php) geduid. Hiermee zullen de meeste
XSLT en PHP bewerkingen die gebruikt worden, verduidelijkt zijn. De integrale code met
verhelderend commentaar is ook in bijlagen D en E te vinden.
Op de pagina staat een zoekformulier waarmee er op drie manieren een opdracht gegeven kan
worden:
1. Een specifieke zoekopdracht waarbij via meerdere velden tegelijk meerdere attributen aan
hun voorwaarden moeten voldoen. Een knoop wordt alleen weerhouden als elke zoekterm
in zijn respectievelijke veld gevonden is (EN).
2. Het alternatief houdt in dat men op alles zoekt. Hierbij wordt er in één veld een zoekterm
ingevuld, die dan met alle attributen vergeleken wordt. Een knoop wordt dan weerhouden
als de zoekterm in één of meerdere van alle attributen gevonden wordt (OF).
3. Er is ook een mogelijkheid om te herbeginnen (reset). Na een reset wordt geen enkele
filter toegepast en het resultaat geeft dan alle vakken weer.
De zoekopdracht wordt vervolgens door een HTML formulier met de „get‟ methode via de
URL parameters doorgegeven. De functie zetVoorwaarde() haalt de input uit de parameters
op en verwerkt ze tot strings die dan in $xsl ingevoegd worden. zetVoorwaarde detecteert
welk van de drie mogelijkheden gebruikt worden en zal dan de variabele $xslvoorwaarde aan
de zoekopdracht van de gebruiker aanpassen. Indien een reset gevraagd is of er nog geen
zoekopdracht doorgegeven is, zal $xslvoorwaarde geen echte test bevatten. Als er wel een
zoekopdracht is, zal ze een aaneenschakeling van testen op attributen zijn. Hierna volgt een
voorbeeld van een test op 1 attribuut:
contains(translate(Vak, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')
$alles is de waarde die de gebruiker zelf opgegeven heeft. Die is via door PHP functies al
vertaald naar kleine letters en ontdaan van problematische karakters. Deze voorwaarde kijkt
of de waarde die de gebruiker opgegeven heeft, in de waarde van „Vak‟ (door translate() ook
naar kleine letters vertaalt), voorkomt. Merk op dat men hier tot XSLT 1.0 beperkt is en dus
de XSL functie translate() de enige manier is om de vertaling te realiseren. Voor elk attribuut
is er een dergelijke test en deze testen worden in dit geval aaneengeschakeld met behulp van
16
de booleaanse of (or). Indien niet op alles, maar op specifiekere voorwaarden gezocht zou
worden, zou dit de booleaanse en (and) zijn.
De zoekvoorwaarden die opgegeven zijn, zullen gehandhaafd blijven totdat er op andere
voorwaarden gezocht wordt of er een reset is. De gehanteerde zoekvoorwaarden worden ook
reeds in het zoekformulier ingevuld zodat de zoekopdracht voor de gebruiker eenvoudig te
zien is en ook eenvoudig aangepast kan worden.
Verder moeten de vakken gesorteerd worden. De gebruiker kan door op de kolomhoofding
van een attribuut te klikken, de data oplopend op dit attribuut sorteren. Een tweede klik
sorteert aflopend. Er is ook en standaardwaarde ($sorteer_default) waarop gesorteerd wordt
indien er geen attribuut gespecificeerd is. Er wordt ook secundair op de naam van het vak
gesorteerd. Dit betekent dat indien er bijvoorbeeld op lesgever gesorteerd wordt en één
lesgever meerdere vakken geeft, deze vakken in alfabetische volgorde van hun naam
weergegeven worden. Hier volgt de code in XSLT dat voor de sortering op aanvraag zorgt:
<xsl:sort select="translate($sorteer,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"
order="$order" />
Ook hier wordt er voor een translate naar kleine letters gezorgd. Dit om ervoor te zorgen dat
indien er op bijvoorbeeld de Fea codes gesorteerd wordt, de codes die beginnen met een
hoofdletter niet de rest „voorbijsteken‟. In $sorteer wordt de keuze van waarop gesorteerd
moet worden ingevuld en $order bepaalt de volgorde (ascending of descending).
Na het selecteren van de vakken en het sorteren van het resultaat, moet de hoeveelheid data
die getoond wordt, beperkt worden. Wanneer er nog niet gezocht wordt, zijn alle 696 vakken
geselecteerd. Dit mag natuurlijk niet allemaal tegelijk getoond worden. Daarom worden er
telkens maar 10 knopen (vakken) weergegeven. Men kan kiezen om de volgende tien of de
vorige tien vakken weer te geven. De functie zetGrens() handelt de logica af en vult
$ondergrens en $bovengrens in. Deze worden dan in de volgende XSLT code ingevuld:
<xsl:if test="position() <= $bovengrens and position() >
$ondergrens">
Dit is een logische XSLT test die kijkt of de positie van de momenteel te evalueren knoop,
binnen de huidige grenzen ligt. Indien dit zo is, zal alle code tussen deze tag en haar einde
</xsl:if>, uitgevoerd worden.
17
De functie xslSamenstellen() vult alle variabelen in de XSLT stylesheet $xsl in. Een aantal
zaken van die stylesheet zijn nog niet verduidelijkt. De stylesheet begint met de volgende lijn:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Dit is een eenvoudige declaratie waarmee de versie vastgelegd wordt op 1.0 en xmlns:xsl
definieert een namespace voor xsl. Op het einde van de stylesheet wordt door
</xsl:stylesheet> de stylesheet tag gesloten.
De outputmethode moet hiërarchisch direct onder de stylesheet komen en niet dieper in het
document. Deze legt het formaat van de output vast. Standaard is dit xml. Encoding regelt de
codering van de output. Indent zorgt dat de output zal inspringen volgens de hiërarchische
structuur.[21] Dit maakt de broncode meer leesbaar.
<xsl:output method="html" encoding="utf-8" indent="yes" />
Binnenin het element xsl:template komt alle code voor de output. Hierbinnen kan HTML
code geschreven worden. Met match kan er een pad opgegeven worden binnen de XML data.
Hier wordt alleen “/” opgegeven waardoor binnenin dit element men het volledige pad, met
dataroot inclusief, moet opgeven om bepaalde knopen aan te spreken.
<xsl:template match="/">
De meeste zaken die hierbinnen staan zijn niet meer dan HTML met af een toe een PHP
variable die ingevuld wordt.
De volgende code spreekt een extern XML document (en dus niet het webdata.xml dat
standaard aangesproken wordt) aan. Uit Studiejaren.xml worden dan de Fea codes gehaald en
in een tabel geplaatst. Voor het externe Studiejaren.xml is de functie document() nodig. De
codes zelf worden in een link geplaatst waarmee een zoekopdracht gegeven of verfijnd kan
worden. Bovendien krijgt deze link als titel de volledige naam van de opleiding zodat
wanneer men de muisaanwijzer erboven plaatst deze informatie getoond wordt.
<xsl:for-each
select="document('xml/Studiejaren.xml')/dataroot/Studiejaren">
De tweede keer dat er een xsl:for-each statement gebruikt wordt, is dit om de vakken te
selecteren. Hier wordt er wel in webdata.xml genavigeerd (/dataroot/webdata) en tussen de
vierkante haken wordt de $xslvoorwaarde ingevuld:
18
<xsl:for-each select="/dataroot/webdata[($xslvoorwaarde) and
(generate-id(.) = generate-id(key('uniqueselect', NR)[1]))]">
<xsl:key name="uniqueselect" match="webdata[($xslvoorwaarde)]"
use="NR" />
De sleutel (key), uniqueselect, waarnaar hier verwezen wordt, werd eerder gedeclareerd. In de
select statement is er aan de $xslvoorwaarde een additionele voorwaarde toegevoegd. Deze
voorwaarde zorgt ervoor dat de meerdere variaties van vakken niet als meerdere vakken
weergegeven worden. In XSLT 2.0 wordt dat opgelost met behulp van de xsl:for-each-group,
maar in XSLT 1.0 is er geen ingebouwde ondersteuning en moet dit anders gebeuren. De
manier waarop dit gerealiseerd wordt, is via de „Muenchian grouping method‟. Deze methode
is populair, eenvoudig toepasbaar en vrij efficiënt.[22] Ze is vernoemd naar Steve Muench die
ze oorspronkelijk voorgesteld heeft.[23]
Merk op dat aan de sleutel ook de $xslvoorwaarde toegevoegd is. Indien dit niet het geval
was, zou alleen de eerste keer dat een vaknummer (NR) voorkomt, zijn knoop geselecteerd
kunnen worden. Stel bijvoorbeeld dat twee lesgevers hetzelfde vak geven en dat deze dan ook
als twee records in de databank voorkomem. Als men zoekt naar degene die toevallig eerst
staat, zou dat geen probleem geven. Zoekt men echter naar de tweede, dan zou de Muenchian
grouping verhinderen dat je deze vindt omdat alleen de eerste node voorbij de test zou
geraken.
De waarden van attributen kunnen uit de xml gehaald worden met behulp van:
<xsl:value-of select="NR"/>
Dit selecteert het nummer van het huidige vak. Merk op dat er ook meer complexe
uitdrukkingen binnenin de aanhalingstekens kunnen geplaatst worden. Zo wordt met behulp
van de volgende code een URL samengesteld die aan de huidige zoekopdracht een
zoekopdracht naar de lesgever toevoegt:
<xsl:value-of select="concat('zoek.php?', 'vaknaam=$zoekVak',
'&', 'lesgever=', Lesgever, '&', 'vakgroep=$vakgroep',
'&', 'vakcode=$vakcode', '&',
'studiejaar=$studiejaar')" />
Het zoeken naar Referentiewerken (zoekRef.php) is, zoals eerder vermeld, erg gelijkaardig.
Een belangrijk verschil is dat er bij de referentiewerken geen tabel met mogelijke Fea
zoekwaarden moet weergegeven worden. Verder moet er ook rekening mee gehouden worden
19
dat ISBN nummers in de databank met en zonder liggende strepen kunnen voorkomen. Van
de gebruikersinput worden alle liggende strepen en spaties verwijderd zodat ze geen
problemen kunnen geven.
4.4 Details van vakken en referentiewerken
De integrale code met verduidelijkend commentaar is ook van deze pagina‟s in bijlagen F en
G te vinden. De detailpagina‟s maken gebruik van dezelfde technieken als de zoekpagina‟s.
Maar er zijn natuurlijk ook verschillen.
Een eerste belangrijk verschil is dat er geen zoekopdracht moet verwerkt worden. Het enige
wat uit de URL parameters gehaald wordt om het juiste vak- of referentiewerk te selecteren, is
het vak- of referentiewerknummer. Met dat nummer wordt dan de juiste knoop geselecteerd
voor het weergeven van de informatie.
De opzoeking van de vak- of referentiewerkdetails en het zoeken naar de gerelateerde
referentiewerken, respectievelijk vakken, is opgesplitst. Bij de vakken zijn de vakdetails nog
verder opgesplitst. Eerst worden de vakcode, vaknaam en aanwezigheid met behulp van
Muenchian grouping weergegeven. Daarna is er een select zonder Muenchian grouping zodat
alle knopen van het vak geselecteerd worden. Alle combinaties van lesgever en studiejaar
worden zo getoond. Vervolgens moet ook de ECTS fiche van het vak weergegeven worden.
Om de referentiewerken die bij een vak horen te vinden, is RefNrVakNr.xml nodig. In die
XML staan de combinaties van vakken en referentiewerken. Voor elk gebruik van een
referentiewerk, worden daarin het vaknummer en het referentiewerknummer in een
RefNrVakNr element gecombineerd. Uiteindelijk moet voor een bepaald vak dus elk
referentiewerk dat aan dit vak gekoppeld is, geselecteerd worden. De stylesheet die dat zal
doen, wordt eerst zelf uit RefVakNr samengesteld. Er zijn dus twee XSLT operaties. De
eerste haalt data uit RefVakNr.xml, meer specifiek de referentieverwijzingen van het vak, en
heeft als ouptut een nieuwe XSLT stylesheet. Die stylesheet wordt dan als de input stylesheet
gebruikt om de juiste referentiewerken te selecteren. Deze oplossing kan omslachtig lijken,
maar op deze manier moeten alle elementen het volledige RefVakNr.xml één keer doorlopen
worden en het volledige Referentiewerken.xml ook één keer. Deze twee doorlopingen
gebeuren sequentieel en om de totale tijd te bekomen moet men dus alleen de twee
individuele tijden optellen. De XSLT processor wordt maar één keer aangemaakt en moet hoe
dan ook de twee XML documenten inladen.
20
Voor de referentiewerken pagina is de werkwijze analoog, maar dan in omgekeerde richting.
Bij de referentiewerken is er ook de mogelijkheid voorzien om eenvoudig een referentiewerk
extern op te zoeken. Er zijn linken voorzien om bij Google en de centrale UGent bibliotheek
het referentiewerk te zoeken.
21
5. Besluit
Er bestond al een bibliotheeksite met een zoeksysteem voor de cursussen. Er zijn echter
verscheidene aanpassingen en verbeteringen gewenst. Zo mag het systeem van de website niet
langer afhankelijk zijn van Acces en IIS opdat het zo geen specifieke eisen aan de
serverinfrastructuur stelt. Bovendien moest het mogelijk zijn de oude Access databank te
blijven gebruiken. Het systeem moest ook voor externe databronnen importvriendelijker
worden. Verder moet de informatie omtrent de referentiewerken dan ook beschikbaar gesteld
worden. Ten slotte mag het probleem waarbij één vak als meerdere weergeven wordt, niet
meer voorkomen.
De aan databank- en serverafhankelijkheid gerelateerde vereisten zijn opgelost door het
gebruik van XML en XSLT. Alhoewel de website nu PHP nodig heeft, is dit een veel
beperktere platformafhankelijkheid dan het oude.NET en IIS. XML maakt ook importering
van data vanuit externe databanken eenvoudiger. Ook de functionaliteituitbreiding is
gerealiseerd nu de link tussen de vakken en referentiewerken eenvoudig te zien is op de vak-
en referentiewerkpagina‟s. Er kan nu op referentiewerken gezocht worden. Meerdere variaties
van één vak, worden nu als één vak weergegeven. Op de detailpagina van een vak zijn nu de
details van de variaties te vinden.
Er is overwogen om met Symphony CMS aan de slag te gaan, maar hiermee werd om
meerdere redenen uiteindelijk niet doorgegaan. Dit betekent echter niet dat er geen
contentmanagement gerealiseerd is. Zoals een begin van paragraaf 3.2 duidelijk gemaakt is, is
het begrip contentmanagement ruimer en gaat het over het systematisch beheer van content,
gegevens en data. Het organiseren van de data in XML formaat en dit dan via de website aan
de gebruiker beschikbaar stellen is op zich al een vorm van contentmanagement.
Er kan aldus besloten worden dat het hier ontwikkelde zoeksysteem op een relatief efficiënte
wijze tegemoet komt aan de gewenste verbeteringen.
22
Bijlagen
Bijlage A: XML webdata voorbeeld De 4 records uit figuur 1 naar XML geëxporteerd. Merk op dat de regelinsprong achteraf toegevoegd
is om dit meer leesbaar en duidelijk te maken.
23
Bijlage B: Systeem
De volgende configuratie werd voor alle experimenten en ontwikkeling gehanteerd:
Server2Go 1.8.2 met PHP 5.3.2, SQLite, MySQL 5.1.46
Dit draaide op: Packard Bell EasyNote TJ75 met:
Windows 7 Home Premium, 64bit, Service pack 1
Intel core i3 330M @ 2.13GHz 2.13GHz
4GB DDR3
24
Bijlage C: Een voudige stylesheet om een vak op lesgever te zoeken
$url-Lesgever is een Symphony parameter die de waarde die van de url parameter Lesgever
binnen de page template(XSLT stylesheet) beschikbaar maakt. Wanneer echter speciale
tekens die in namen kunnen voorkomen, zoals é, è, en ç, gebruikt worden, leidt dit tot een
faling van XSLT.
25
Bijlage D: Code van de vakzoekfunctie - zoek.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cursusbibliotheek</title>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<link rel="stylesheet" type="text/css" href="Stylesheet.css" />
</head>
<body>
<div id="begintekst">
Zoeken naar: <b>Vakken</b> <a
href="zoekRef.php">Referentiewerken</a>
</div>
<?php
//$sorteer_default is de waarde waarop de resultaten standaard
gesorteerd wanneer de gebruiker geen specifieke sorteeropdracht gegeven
heeft.
/*De eerste twee variabelen zijn in te stellen parameters.
$sorteer_default stelt in op welk attribuut er standaard gesorteerd wordt.
$aantal_per_rij bepaalt het aantal Fea(FirW) codes dat per rij weergegeven
wordt.
*/
$sorteer_default='FTWafkorting';
$aantal_per_rij=13;
$alles;
$zoekVak;
$lesgever;
$vakgroep;
$vakcode;
$studiejaar;
$bovengrens;
$ondergrens;
$xslvoorwaarde;
$sorteer;
$order;
$vorig_sorteren;
$xsl;
$processor = new XSLTProcessor();
/*zetGrens() zal ervoor zorgen dat er maar 10 nodes per keer getoond
worden. Deze twee grenzen worden dan verder in
xslSamenstellen() in de xsl ingevuld.
*/
function zetGrens() {
global $bovengrens;
global $ondergrens;
if(isset($_GET["bovengrens"])) {
26
$bovengrens=$_GET["bovengrens"];
}
else{$bovengrens=10;}
if(isset($_GET["Vorige"])) {
if($bovengrens>10){
$bovengrens=max($bovengrens-10,10);
}
else
{$bovengrens=10;}
}
if(isset($_GET["Volgende"])) {
$bovengrens=$bovengrens+10;
}
$ondergrens = $bovengrens-10;
}
/*zetVoorwaarde() zal de input van de gebruiker verwerken en die in
variabelen(strings) plaatsen. Die worden dan later
in xslSamenstellen() in de xsl ingevuld.
*/
function zetVoorwaarde() {
/*Om characters die xslt problemen kan geven te vermijden, kan met de
volgende twee arrays een lijst met oplossingen voor dit probleem voorzien
worden.
*/
$tevervangen = array("'", '"', '<', '>', '\\', '&', '{', '}');
$vervanging = array('', '', '', '', '', '', '', '');
global $sorteer_default;
global $alles;
global $zoekVak;
global $lesgever;
global $vakgroep;
global $vakcode;
global $studiejaar;
global $xslvoorwaarde;
global $sorteer;
global $order;
global $vorig_sorteren;
/*OF Als een reset gevraagd is.
OF Als er nog niets gezocht wordt.
Alle variabelen worden op hun(lege) standaardwaarden gezet en er wordt op
geen zoekopdracht gefilterd.
*/
if(isset($_GET["reset"]) or !(isset($_GET["alles"]) or
isset($_GET["vaknaam"])or isset($_GET["lesgever"]) or
isset($_GET["vakgroep"])or isset($_GET["vakcode"]) or
isset($_GET["studiejaar"]) )) {
$alles = '';
$zoekVak = '';
27
$lesgever = '';
$vakgroep = '';
$vakcode = '';
$studiejaar = '';
$xslvoorwaarde = '1=1';
}
else {
//Indien er op alles tegelijk gezocht wordt, zal alleen
dit veld in rekening genomen worden.
if(isset($_GET["alles"])) {
$alles = $_GET["alles"];
$alles = strtr($alles,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$alles = str_replace($tevervangen, $vervanging,
$alles);
$xslvoorwaarde = <<<heredoc
(contains(translate(Vak, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')or contains(translate(Lesgever,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$alles')or
contains(translate(EersteVanVakgr, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')or contains(translate(NR,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$alles')or
contains(translate(FirstOfstudiejaarcode, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')or contains(translate(FTWafkorting,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$alles'))
heredoc;
}
//Indien er niet op alles gezocht wordt, wordt er een
specefiekere zoekopdracht opgesteld.
else {
if(isset($_GET["vaknaam"])){
$zoekVak = $_GET["vaknaam"];
$zoekVak = strtr($zoekVak,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$zoekVak = str_replace($tevervangen,
$vervanging, $zoekVak);
}
else {$zoekVak='';}
if(isset($_GET["lesgever"])){
$lesgever = $_GET["lesgever"];
$lesgever = strtr($lesgever,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$lesgever = str_replace($tevervangen,
$vervanging, $lesgever);
}
else {$lesgever='';}
if(isset($_GET["vakgroep"])){
$vakgroep = $_GET["vakgroep"];
$vakgroep = strtr($vakgroep,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$vakgroep = str_replace($tevervangen,
$vervanging, $vakgroep);
}
else {$vakgroep='';}
if(isset($_GET["vakcode"])){
$vakcode = $_GET["vakcode"];
$vakcode = strtr($vakcode,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
28
$vakcode = str_replace($tevervangen,
$vervanging, $vakcode);
}
else {$vakcode='';}
if(isset($_GET["studiejaar"])){
$studiejaar = $_GET["studiejaar"];
$studiejaar = strtr($studiejaar,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$studiejaar = str_replace($tevervangen,
$vervanging, $studiejaar);
}
else {$studiejaar='';}
$xslvoorwaarde = <<<heredoc
(contains(translate(Vak, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$zoekVak')and contains(translate(Lesgever,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$lesgever')and
contains(translate(EersteVanVakgr, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$vakgroep')and contains(translate(NR,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$vakcode')and
contains(translate(FirstOfstudiejaarcode, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$studiejaar'))
heredoc;
}
}
//Indien de sorteervoorwaarde door de gebruiker gevraagd is,
wordt ze hier in rekening genomen.
if(isset($_GET["sorteer"])&&($_GET["sorteer"]!='')){
$sorteer = $_GET["sorteer"];
if($sorteer == 'Vakcode') {$sorteer = 'NR';}
if($sorteer == 'Vak') {$sorteer = 'Vak';}
if($sorteer == 'Lesgever') {$sorteer = 'Lesgever';}
if($sorteer == 'Vakgroep') {$sorteer = 'EersteVanVakgr';}
if($sorteer == 'Studiejaar') {$sorteer =
'FirstOfstudiejaarcode';}
if($sorteer == 'Fea') {$sorteer = 'FTWafkorting';}
if($sorteer == 'Aanwezig') {$sorteer = 'Aanwezig';}
$vorig_sorteren = $sorteer;
/*Daarna moet er ook nog in de juiste richting gesorteerd
worden. Standaard is dat oplopend. Maar als er
een tweede keer sortering van eenzelfde vak gevraagd wordt, zal
dit aflopend worden. Controleren of het
om hetzelfde vak gaat, gebeurt via $_GET["vorig_sorteren"].
*/
$vorig_sorteren = $sorteer;
if((isset($_GET["vorig_sorteren"]))&&($_GET["vorig_sorteren"]!='')) {
if($_GET["vorig_sorteren"]==$sorteer) {
$order = 'descending';}
else {$order = 'ascending';}
$vorig_sorteren = '';
}
else {
$order='ascending';
}
}
29
//Standaard(indien geen sorteerverzoek is) op default sorteren.
else {
$sorteer = $sorteer_default;
$order = 'ascending';
}
}
function xslSamenstellen() {
global $xsl;
global $alles;
$allesdoorgeven;
if($alles!='') $allesdoorgeven=<<<heredoc
<input type="hidden" name="alles" value="$alles" />
heredoc;
global $aantal_per_rij;
global $zoekVak;
global $lesgever;
global $vakgroep;
global $vakcode;
global $studiejaar;
global $bovengrens;
global $ondergrens;
global $xslvoorwaarde;
global $sorteer;
global $order;
global $vorig_sorteren;
$xsl = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:key name="uniqueselect" match="webdata[($xslvoorwaarde)]"
use="NR" />
<xsl:template match="/">
<div id="zoekformulier">
<table id="zoektabel">
<form method="get" action="zoek.php">
<tr>
<td><i>U kan op alle velden zoeken:</i></td>
<td><input name="alles" type="text" size="70"
value="$alles" /></td>
<td align="right"><input type="submit"
value="Zoekopdracht verzenden" /></td>
</tr>
</form>
<form method="get" action="zoek.php">
<tr>
<td colspan="2"><i>Of op één of meer velden
tegelijkertijd:</i></td>
<td align="right">Reset: <input type="submit"
name="reset" value="Herbeginnen" /></td>
</tr>
30
</form>
<form method="get" action="zoek.php">
<tr>
<td>Naam van het vak:</td>
<td colspan="2"><input name="vaknaam" type="text"
size="70" value="$zoekVak" /></td>
</tr>
<tr>
<td>Naam lesgever:</td>
<td><input name="lesgever" type="text" size="40"
value="$lesgever" /></td>
<td>Vakgroep: <input name="vakgroep" type="text"
size="4" maxlength="4" value="$vakgroep" /></td>
</tr>
<tr>
<td>Vakcode: <input name="vakcode" type="text"
size="7" maxlength="7" value="$vakcode" /></td>
<td>Studiejaar: <input name="studiejaar"
type="text" size="9" value="$studiejaar" /></td>
<td align="right"><input type="submit"
value="Zoekopdracht verzenden" /></td>
</tr>
</form>
</table>
<table id="studiejaren">
<xsl:for-each
select="document('xml/Studiejaren.xml')/dataroot/Studiejaren">
<xsl:sort select="FTWafkorting" />
<xsl:choose>
<xsl:when test="position() mod $aantal_per_rij =
1">
<xsl:text disable-output-
escaping="yes"><tr></xsl:text>
</xsl:when>
</xsl:choose>
<td>
<xsl:element name="a">
<xsl:attribute name="href" >
<xsl:value-of
select="concat('zoek.php?', 'vaknaam=$zoekVak', '&',
'lesgever=$lesgever', '&', 'vakgroep=$vakgroep', '&',
'vakcode=$vakcode', '&', 'studiejaar=', Studiejaarcode)" />
</xsl:attribute>
<xsl:attribute name="title" >
<xsl:value-of
select="concat('Richting: ', Studiejaarnaam, ' Studiejaar: ',
Studiejaarcode)" />
</xsl:attribute>
<xsl:value-of select="FTWafkorting" />
</xsl:element>
</td>
<xsl:choose>
<xsl:when test="position() mod $aantal_per_rij =
0">
<xsl:text disable-output-
escaping="yes"></tr></xsl:text>
</xsl:when>
</xsl:choose>
</xsl:for-each>
31
</table>
</div>
<div id="zoekresultaat">
<table id="resultaattabel">
<tr id="zoekhoofding">
<form method="get" action="zoek.php">
<input type="hidden" name="vaknaam" value="$zoekVak"/>
<input type="hidden" name="lesgever" value="$lesgever"/>
<input type="hidden" name="vakgroep" value="$vakgroep"/>
<input type="hidden" name="vakcode" value="$vakcode"/>
<input type="hidden" name="studiejaar"
value="$studiejaar"/>
<input type="hidden" name="vorig_sorteren"
value="$vorig_sorteren" />
$allesdoorgeven
<td>Info</td>
<td style="width:80px">
<input type="submit" name="sorteer"
value="Vakcode"/>
</td>
<td style="width:350px">
<input type="submit" name="sorteer" value="Vak"/>
</td>
<td style="width:160px">
<input type="submit" name="sorteer"
value="Lesgever"/>
</td>
<td style="width:80px">
<input type="submit" name="sorteer"
value="Vakgroep"/>
</td>
<td style="width:100px">
<input type="submit" name="sorteer"
value="Studiejaar"/>
</td>
<td style="width:75px">
<input type="submit" name="sorteer" value="Fea"/>
</td>
<td>
<input type="submit" name="sorteer"
value="Aanwezig"/>
</td>
</form>
</tr>
<xsl:for-each select="/dataroot/webdata[($xslvoorwaarde) and
(generate-id(.) = generate-id(key('uniqueselect', NR)[1]))]">
<xsl:sort select="translate($sorteer,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" order="$order"
/>
<xsl:sort select="Vak" order="ascending" />
<xsl:if test="position() <= $bovengrens and position()
> $ondergrens">
<xsl:element name="tr">
<xsl:attribute name="id">
<xsl:choose>
32
<xsl:when test="position() mod 2 =
1">oneven</xsl:when>
<xsl:otherwise>even</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<form method="get" action="detail.php">
<xsl:element name="input">
<xsl:attribute
name="type">hidden</xsl:attribute>
<xsl:attribute
name="name">NR</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="NR"/>
</xsl:attribute>
</xsl:element>
<input type="image"
src="afbeeldingen/Details.gif" alt="Bekijk Details"/>
</form>
</td>
<td>
<xsl:value-of select="NR"/>
</td>
<td>
<xsl:value-of select="Vak"/>
</td>
<td>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of
select="concat('zoek.php?', 'vaknaam=$zoekVak', '&', 'lesgever=',
Lesgever, '&', 'vakgroep=$vakgroep', '&', 'vakcode=$vakcode',
'&', 'studiejaar=$studiejaar')" />
</xsl:attribute>
<xsl:value-of select="Lesgever"/>
</xsl:element>
</td>
<td>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of
select="concat('zoek.php?', 'vaknaam=$zoekVak', '&',
'lesgever=$lesgever', '&', 'vakgroep=', EersteVanVakgr, '&',
'vakcode=$vakcode', '&', 'studiejaar=$studiejaar')" />
</xsl:attribute>
<xsl:value-of select="EersteVanVakgr"/>
</xsl:element>
</td>
<td>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of
select="concat('zoek.php?', 'vaknaam=$zoekVak', '&',
'lesgever=$lesgever', '&', 'vakgroep=$vakgroep', '&',
'vakcode=$vakcode', '&', 'studiejaar=', FirstOfstudiejaarcode)" />
</xsl:attribute>
<xsl:value-of
select="FirstOfstudiejaarcode"/>
33
</xsl:element>
</td>
<td>
<xsl:value-of select="FTWafkorting"/>
</td>
<td>
<xsl:if test="Aanwezig=-1">Ja</xsl:if>
<xsl:if test="Aanwezig=0">Nee</xsl:if>
</td>
</xsl:element>
</xsl:if>
</xsl:for-each>
<form method="get" action="zoek.php">
<tr id="zoekonderbalk">
<td colspan="6">
Resultaat $ondergrens tot $bovengrens van
<xsl:value-of select = "count(dataroot/webdata[($xslvoorwaarde)and
(generate-id(.) = generate-id(key('uniqueselect', NR)[1]))])" />
</td>
<td colspan="2">
<input type="hidden" name="vaknaam"
value="$zoekVak"/>
<input type="hidden" name="lesgever"
value="$lesgever"/>
<input type="hidden" name="vakgroep"
value="$vakgroep"/>
<input type="hidden" name="vakcode"
value="$vakcode"/>
<input type="hidden" name="studiejaar"
value="$studiejaar"/>
<input type="hidden" name="bovengrens"
value="$bovengrens"/>
<input type="hidden" name="sorteer"
value="$sorteer" />
<input type="hidden" name="order" value="$order" />
$allesdoorgeven
<input type="submit" name="Vorige" value="Vorige"/>
<input type="submit" name="Volgende"
value="Volgende"/>
</td>
</tr>
</form>
</table>
</div>
<div id="eindtekst">
<p>Klik op het vergrootglas voor de vakgegevens, ECTS-fiche en
referentiewerken.</p>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function outputXSLT() {
global $xsl;
global $processor;
34
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/webdata.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
//Hierna worden de bovenstaande functies in de juiste volgorde
aangesproken om de content te genereren.
zetGrens();
zetVoorwaarde();
xslSamenstellen();
outputXSLT();
?>
</body>
</html>
35
Bijlage E: Code van de Referentiewerkzoekfunctie - zoekRef.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cursusbibliotheek</title>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<link rel="stylesheet" type="text/css" href="Stylesheet.css" />
</head>
<body>
<div id="begintekst">
Zoeken naar: <a href="zoek.php">Vakken</a>
<b>Referentiewerken</b>
</div>
<?php
$sorteer_default='Titel';
$alles;
$Titel;
$Auteur;
$Uitgever;
$ISBN;
$LCNR;
$Aleph_nummer;
$bovengrens;
$ondergrens;
$sorteer;
$order;
$vorig_sorteren;
$xslvoorwaarde;
$xsl;
$processor = new XSLTProcessor();
function zetGrens() {
global $bovengrens;
global $ondergrens;
if(isset($_GET["bovengrens"])) {
$bovengrens=$_GET["bovengrens"];
}
else{$bovengrens=10;}
if(isset($_GET["Vorige"])) {
if($bovengrens>10){
$bovengrens=max($bovengrens-10,10);
}
else
{$bovengrens=10;}
}
if(isset($_GET["Volgende"])) {
$bovengrens=$bovengrens+10;
36
}
$ondergrens = $bovengrens-10;
}
function zetVoorwaarde() {
/*Om characters die xslt problemen kan geven te vermijden, kan met de
volgende twee arrays een lijst met oplossingen voor dit probleem voorzien
worden.
*/
$tevervangen = array("'", '"', '<', '>', '\\', '&', '{', '}');
$vervanging = array('', '', '', '', '', '', '', '');
global $alles;
global $Titel;
global $Auteur;
global $Uitgever;
global $ISBN;
global $LCNR;
global $Aleph_nummer;
global $sorteer_default;
global $sorteer;
global $order;
global $vorig_sorteren;
global $xslvoorwaarde;
/*Als een reset gevraagd is, of als er nog niets gezocht wordt,
worden alle variabelen leeggemaakt of op hun standaardwaarden
gezet.
*/
if((isset($_GET["reset"]))or !(isset($_GET["alles"]) or
isset($_GET["Titel"]) or isset($_GET["Auteur"]) or isset($_GET["Uitgever"])
or isset($_GET["ISBN"]) or isset($_GET["LCNR"]) or isset($_GET["Aleph-
nummer"]))) {
$alles = '';
$Titel = '';
$Auteur = '';
$Uitgever = '';
$ISBN = '';
$LCNR = '';
$Aleph_nummer = '';
$xslvoorwaarde = <<<heredoc
1=1
heredoc;
$sorteer = $sorteer_default;
$order='ascending';
}
else {
//Indien er op alles tegelijk gezocht wordt, zal alleen
dit veld in rekening genomen worden.
if(isset($_GET["alles"])) {
37
$alles = $_GET["alles"];
$alles = strtr($alles,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$alles = str_replace($tevervangen, $vervanging,
$alles);
/*ISBN-nummers kunnen liggende strepen bevatten of
aaneengeschreven zijn. Beide varianten komen voor in de databank.
Daarom moeten alle ISBN nummers naar een spatie- en
streepjesloze versie geconverteerd worden. Ook de ISBN's uit de
referentiewerken.xml worden van streepjes en spaties
ontdaan.
*/
$ISBN_alles = str_replace(' ','',str_replace ('-
','',$alles));
$xslvoorwaarde = <<<heredoc
(contains(translate(Titel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles') or contains(translate(Auteur,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$alles') or
contains(translate(Uitgever, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')or
contains(translate(translate(ISBN, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'), '- ', ''),'$ISBN_alles')or
contains(translate(LCNR, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$alles')or contains(translate(Aleph-nummer,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$alles'))
heredoc;
}
//Indien er niet op alles gezocht wordt, wordt er een
specefiekere zoekopdracht opgesteld.
else {
if(isset($_GET["Titel"])){
$Titel = $_GET["Titel"];
$Titel = strtr($Titel,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$Titel = str_replace($tevervangen,
$vervanging, $Titel);
}
else {$Titel='';}
if(isset($_GET["Auteur"])){
$Auteur = $_GET["Auteur"];
$Auteur = strtr($Auteur,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$Auteur = str_replace($tevervangen,
$vervanging, $Auteur);
}
else {$Auteur='';}
if(isset($_GET["Uitgever"])){
$Uitgever = $_GET["Uitgever"];
$Uitgever = strtr($Uitgever,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$Uitgever = str_replace($tevervangen,
$vervanging, $Uitgever);
}
else {$Uitgever='';}
if(isset($_GET["ISBN"])){
$ISBN = $_GET["ISBN"];
$ISBN = strtr($ISBN,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
38
$ISBN = str_replace($tevervangen, $vervanging,
$ISBN);
/*ISBN-nummers kunnen liggende strepen bevatten of
aaneengeschreven zijn. Beide varianten komen voor in de databank.
Daarom moeten alle ISBN nummers naar een spatie en
streepjesloze versie geconverteerd worden. Ook de ISBN's uit de
referentiewerken.xml worden van streepjes en spaties
ontdaan.
*/
$ISBN = str_replace(' ','',str_replace ('-
','',$ISBN));
}
else {$ISBN='';}
if(isset($_GET["LCNR"])){
$LCNR = $_GET["LCNR"];
$LCNR = strtr($LCNR,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$LCNR = str_replace($tevervangen, $vervanging,
$LCNR);
}
else {$LCNR='';}
if(isset($_GET["Aleph-nummer"])){
$Aleph_nummer = $_GET["Aleph-nummer"];
$Aleph_nummer = strtr($Aleph_nummer,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
$Aleph_nummer = str_replace($tevervangen,
$vervanging, $Aleph_nummer);
}
else {$Aleph_nummer='';}
$xslvoorwaarde=<<<heredoc
contains(translate(Titel, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$Titel')and contains(translate(Auteur,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'$Auteur')and
contains(translate(Uitgever, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$Uitgever')and
contains(translate(translate(ISBN, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'), '- ', ''),'$ISBN')and
contains(translate(LCNR, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$LCNR')and contains(translate(Aleph-nummer,
'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
'abcdefghijklmnopqrstuvwxyz'),'$Aleph_nummer')
heredoc;
}
}
//Indien de sorteervoorwaarde door de gebruiker gevraagd is,
wordt ze hier in rekening genomen.
if(isset($_GET["sorteer"])&&($_GET["sorteer"]!='')){
$sorteer = $_GET["sorteer"];
if($sorteer == 'Vakcode') {$sorteer = 'NR';}
if($sorteer == 'Vak') {$sorteer = 'Vak';}
if($sorteer == 'Lesgever') {$sorteer = 'Lesgever';}
if($sorteer == 'Vakgroep') {$sorteer = 'EersteVanVakgr';}
if($sorteer == 'Studiejaar') {$sorteer =
'FirstOfstudiejaarcode';}
if($sorteer == 'FirW') {$sorteer = 'FTWafkorting';}
/*Daarna moet er ook nog in de juiste richting gesorteerd
worden. Standaard is dat oplopend. Maar als er
39
een tweede keer sortering van eenzelfde vak gevraagd
wordt, zal dit aflopend worden. Controleren of het
om hetzelfde vak gaat, gebeurt via
$_GET["vorig_sorteren"].
*/
$vorig_sorteren = $sorteer;
if((isset($_GET["vorig_sorteren"]))&&($_GET["vorig_sorteren"]!='')) {
if($_GET["vorig_sorteren"]==$sorteer) {
$order = 'descending';}
else {$order = 'ascending';}
$vorig_sorteren = '';
}
else {
$order='ascending';
}
}
//Standaard(indien geen sorteerverzoek is) op ISBN sorteren.
else {
$sorteer =$sorteer_default;
$order='ascending';
}
}
function xslSamenstellen() {
global $xslvoorwaarde;
global $xsl;
global $alles;
$allesdoorgeven;
$allesdoorgeven;
if($alles!='') $allesdoorgeven=<<<heredoc
<input type="hidden" name="alles" value="$alles" />
heredoc;
global $Titel;
global $Auteur;
global $Uitgever;
global $ISBN;
global $LCNR;
global $Aleph_nummer;
global $bovengrens;
global $ondergrens;
global $sorteer;
global $order;
global $vorig_sorteren;
$xsl = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<div id="zoekformulier">
40
<table id="zoektabel">
<form method="get" action="zoekRef.php">
<tr>
<td><i>U kan op alle velden
zoeken:</i></td>
<td colspan="2"><input name="alles"
type="text" size="50" value="$alles" /></td>
<td align="right"><input type="submit"
value="Zoekopdracht verzenden" /></td>
</tr>
</form>
<form method="get" action="zoekRef.php">
<tr>
<td colspan="3"><i>Of op één of meer
velden tegelijkertijd:</i></td>
<td align="right">Reset: <input
type="submit" name="reset" value="Herbeginnen" /></td>
</tr>
</form>
<form method="get" action="zoekRef.php">
<tr>
<td>Titel:</td>
<td colspan="3"><input name="Titel"
type="text" size="50" value="$Titel" /></td>
</tr>
<tr>
<td>Auteur:</td>
<td colspan="3"><input name="Auteur"
type="text" size="50" value="$Auteur" /></td>
</tr>
<tr>
<td>Uitgever:</td>
<td colspan="3"><input name="Uitgever"
type="text" size="50" value="$Uitgever" /></td>
</tr>
<tr>
<td>ISBN: <input name="ISBN" type="text"
size="13" maxlength="13" value="$ISBN" /></td>
<td>LCNR: <input name="LCNR" type="text"
size="15" value="$LCNR" /></td>
<td>Aleph: <input name="Aleph-nummer"
type="text" size="9" maxlength="9" value="$Aleph_nummer" /></td>
<td align="right"><input type="submit"
value="Zoekopdracht verzenden" /></td>
</tr>
</form>
</table>
</div>
<br/>
<div id="zoekresultaat">
<table id="resultaattabel">
<tr id="zoekhoofding">
<form method="get" action="zoekRef.php">
<input type="hidden" name="Titel" value="$Titel"/>
<input type="hidden" name="Auteur" value="$Auteur"/>
<input type="hidden" name="Uitgever" value="$Uitgever"/>
<input type="hidden" name="ISBN" value="$ISBN"/>
41
<input type="hidden" name="LCNR" value="$LCNR"/>
<input type="hidden" name="Aleph-nummer"
value="$Aleph_nummer"/>
<input type="hidden" name="vorig_sorteren"
value="$vorig_sorteren" />
$allesdoorgeven
<td>Info</td>
<td>
<input type="submit" name="sorteer" value="ISBN"/>
</td>
<td style="width:350px">
<input type="submit" name="sorteer" value="Titel"/>
</td>
<td style="width:300px">
<input type="submit" name="sorteer"
value="Auteur"/>
</td>
<td style="width:200px">
<input type="submit" name="sorteer"
value="Uitgever"/>
</td>
<td>
<input type="submit" name="sorteer"
value="Aanwezig"/>
</td>
</form>
</tr>
<xsl:for-each
select="dataroot/Referentiewerken[$xslvoorwaarde]">
<xsl:sort select="$sorteer" order="$order" />
<xsl:sort select="Auteur" order="ascending" />
<xsl:if test="position() <= $bovengrens and position()
> $ondergrens">
<xsl:element name="tr">
<xsl:attribute name="id">
<xsl:choose>
<xsl:when test="position() mod 2 =
1">oneven</xsl:when>
<xsl:otherwise>even</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<form method="get" action="detailRef.php">
<xsl:element name="input">
<xsl:attribute
name="type">hidden</xsl:attribute>
<xsl:attribute
name="name">RefNr</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="RefNr"/>
</xsl:attribute>
</xsl:element>
<input type="image"
src="afbeeldingen/Details.gif" alt="Bekijk Details"/>
</form>
</td>
42
<td>
<xsl:value-of select="ISBN"/>
</td>
<td>
<xsl:value-of select="Titel"/>
</td>
<td>
<xsl:value-of select="Auteur"/>
</td>
<td>
<xsl:value-of select="Uitgever"/>
</td>
<td>
<xsl:if test="Aanwezig=1">Ja</xsl:if>
<xsl:if test="Aanwezig=0">Nee</xsl:if>
</td>
</xsl:element>
</xsl:if>
</xsl:for-each>
<form method="get" action="zoekRef.php">
<tr id="zoekonderbalk">
<td colspan="4">
Resultaat $ondergrens tot $bovengrens van
<xsl:value-of select = "count(dataroot/Referentiewerken[$xslvoorwaarde])"
/>
</td>
<td colspan="2" style="text-align:right">
$allesdoorgeven
<input type="hidden" name="Titel" value="$Titel"/>
<input type="hidden" name="Auteur"
value="$Auteur"/>
<input type="hidden" name="Uitgever"
value="$Uitgever"/>
<input type="hidden" name="ISBN" value="$ISBN"/>
<input type="hidden" name="LCNR" value="$LCNR"/>
<input type="hidden" name="Aleph-nummer"
value="$Aleph_nummer"/>
<input type="hidden" name="bovengrens"
value="$bovengrens"/>
<input type="hidden" name="sorteer"
value="$sorteer" />
<input type="submit" name="Vorige" value="Vorige"/>
<input type="submit" name="Volgende"
value="Volgende"/>
</td>
</tr>
</form>
</table>
</div>
<div id="eindtekst">
<p>Klik op het vergrootglas voor meer gegevens omtrent de
referentiewerken en de vakken die deze werken gebruiken.</p>
<p>Opmerking: Er zijn niet voor alle referentiewerken ISBN,
LCNR en Aleph gegevens in het systeem bekend.</p>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
43
}
function outputXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/Referentiewerken.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
zetGrens();
zetVoorwaarde();
xslSamenstellen();
outputXSLT();
</body>
</html>
44
Bijlage F: Code van de vakdetailpagina - Detail.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cursusbibliotheek</title>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<link rel="stylesheet" type="text/css" href="Stylesheet.css" />
</head>
<body>
<?php
/* De code bestaat uit 2 hoofddelen. Het eerste is verantwoordelijk voor
het weergeven van de vakgegevens en de
pdf info fiche. Het tweede deel toont de referentiewerken die bij het vak
horen.
3 variabelen worden geinitialiseerd. $xsl zal telkens als xsl document aan
de XSLT-processor de instructies geven.
$NR bepaalt het vak en zal als zoekvoorwaarde bij het selecteren van xml
nodes gehanteerd worden.
De XSLT-processor wordt hier éénmalig aangemaakt en verderop telkens
gebruikt om de XSLT transformaties te realiseren.
*/
$xsl;
$NR;
$processor = new XSLTProcessor();
/* Vanaf de zoekpagina worden via de url het NR dat een vak uniek
identificeert, doorgegeven. ZetVoorwaarde()
verwerkt die gegevens in een string die verder gebruikt wordt. Beide delen
hebben dit NR nodig.
*/
function zetVoorwaarde() {
global$NR;
$NR="";
$NR = $_GET["NR"];
}
// DEEL 1 - Vakgegevens en pdf info fiche
/* xslSamenstellen1() zorgt voor de eerste algemene vakgegevens. (NR en
vaknaam)
xslSamenstellen2() zorgt voor de gegevens waarvan er meerdere waarden
kunnen zijn.(lesgever, Studiejaar en FirW)
xslSamenstellen3() zorgt voor de status van Aanwezig en het tonen van
de pdf.
*/
$xsl1;
$xsl2;
$xsl3;
45
function vakdetails() {
global $processor;
global $xsl1;
global $xsl2;
global $xsl3;
xslSamenstellen1();
outputXSLT($xsl1);
xslSamenstellen2();
outputXSLT($xsl2);
xslSamenstellen3();
outputXSLT($xsl3);
}
function xslSamenstellen1() {
global $NR;
global $xsl1;
$xsl1 = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:key name="uniqueselect" match="webdata[(NR='$NR')]" use="NR" />
<xsl:template match="/">
<div id="begintekst">
<h2>Details</h2>
<a href="javascript:history.go(-1)"
title="Terug">Terug</a>
</div>
<div id="vak">
<h3>Vakgegevens</h3>
<xsl:for-each select="dataroot/webdata[(NR='$NR')and (generate-
id(.) = generate-id(key('uniqueselect', NR)[1]))]">
<table>
<tr id="hoofding">
<td colspan="2">
<xsl:text disable-output-escaping="yes">
&nbsp;</xsl:text>
</td>
</tr>
<tr id="oneven">
<td style="width:80px">Vakcode</td>
<td style="width:330px">
<xsl:value-of select="NR"/>
</td>
</tr>
<tr id="even">
<td>Vak</td>
<td>
<xsl:value-of select="Vak"/>
</td>
</tr>
<tr id="oneven">
<td>Aanwezig</td>
<td>
<xsl:if test="Aanwezig=-1">
Ja
46
</xsl:if>
<xsl:if test="Aanwezig=0">
Nee
</xsl:if>
</td>
</tr>
</table>
<br/>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function xslSamenstellen2() {
global $NR;
global $xsl2;
$xsl2 = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<div id="vakdetails">
<table>
<tr id="oneven">
<td style="width:160px">Lesgever</td>
<td style="width:80px">Vakgroep</td>
<td style="width:80px">Studiejaar</td>
<td style="width:80px">Fea</td>
</tr>
<xsl:for-each select="dataroot/webdata[(NR='$NR')]">
<xsl:sort select="Lesgever" />
<xsl:element name="tr">
<xsl:attribute name="id">
<xsl:choose>
<xsl:when test="position() mod 2 =
1">even</xsl:when>
<xsl:otherwise>oneven</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<td>
<xsl:value-of select="Lesgever"/>
</td>
<td>
<xsl:value-of select="EersteVanVakgr"/>
</td>
<td>
<xsl:value-of
select="FirstOfstudiejaarcode"/>
</td>
47
<td>
<xsl:value-of select="FTWafkorting"/>
</td>
</xsl:element>
</xsl:for-each>
<tr id="onderbalk">
<td colspan="4">
<xsl:text disable-output-escaping="yes">
&nbsp;</xsl:text>
</td>
</tr>
</table>
<br/>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function xslSamenstellen3() {
global $NR;
global $xsl3;
$xsl3 = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:key name="uniqueselect" match="webdata[(NR='$NR')]" use="NR" />
<xsl:template match="/">
<div id="pdf">
<xsl:for-each select="dataroot/webdata[(NR='$NR')and (generate-
id(.) = generate-id(key('uniqueselect', NR)[1]))]">
<h3>Studiefiche</h3>
<xsl:element name="iframe">
<xsl:attribute name="src">
<xsl:value-of select="concat(url,
'&','embedded=true')"/>
</xsl:attribute>
<xsl:attribute
name="width">600</xsl:attribute>
<xsl:attribute
name="height">800</xsl:attribute>
<xsl:attribute
name="style">none</xsl:attribute>
</xsl:element>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
/* Het externe xml document met de webdata wordt in een DOMDocument
ingevoerd. Dat DomDocument kan dan aan de
XSLT processor gegeven vie transformToXML(). De xsl-instructies die in
$xmldocument zitten, worden in een SimpleXMLElement
ingevoerd en dan naar de processor geimporteerd.
48
*/
$xmldocument = new DOMDocument();
$xmlLink = 'xml/webdata.xml';
$xmldocument->load($xmlLink);
function outputXSLT($XSLinput) {
global $processor;
global $xmldocument;
$xsldocument = new SimpleXMLElement($XSLinput);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
/*Hierna zijn de functies voor de referentiewerken bij het gegeven vak te
vinden.
De $NR (het vaknummer) kan daarvoor als gegeven aanzien worden.
Eerst worden in de RefNrVakNr.xml de referentiewerken die bij het vak(NR)
horen opgezocht. xslRefSamenstellen() creert de xsl
instructies zo dat het resultaat van de XSLT processor een nieuw XSL-
document is.
Met dat XSL-document als instructies zal dan in Referentiewerken.xml de
gegevens van de referentiewerken opgezocht worden.
*/
function xslRefSamenstellen() {
global $xsl;
global $NR;
$xsl = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<xsl:element name='xsl:stylesheet'>
<xsl:attribute name='version'>1.0</xsl:attribute>
<xsl:element name='xsl:template'>
<xsl:attribute name='match'> / </xsl:attribute>
<div id="referentiewerken">
<h3>Referentiewerken</h3>
<table>
<tr id="hoofding">
<td colspan="4">
<xsl:text disable-output-
escaping="yes"><xsl:text disable-output-escaping="yes">
&amp;nbsp; </xsl:text></xsl:text>
</td>
</tr>
<xsl:for-each
select="dataroot/RefNrVakNr[Nr='{$NR}']">
<tr><td>
<table>
<xsl:element name='xsl:for-each'>
49
<xsl:attribute
name='select'>dataroot/Referentiewerken[RefNr='<xsl:value-of
select="RefNr"/>']</xsl:attribute>
<tr id="oneven">
<td>
<form method="get"
action="detailRef.php">
<xsl:element
name="input">
<xsl:attribute name="type">hidden</xsl:attribute>
<xsl:attribute name="name">RefNr</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="RefNr"/>
</xsl:attribute>
</xsl:element>
<input
type="image" src="afbeeldingen/Details.gif" alt="Bekijk Details"/>
</form>
</td>
<td style="width:420px">
<b>
<xsl:element
name='xsl:value-of'>
<xsl:attribute
name="select">Titel</xsl:attribute>
</xsl:element>
</b>
</td>
</tr>
<tr id="even">
<td></td>
<td>
<xsl:element
name='xsl:value-of'>
<xsl:attribute
name="select">Auteur</xsl:attribute>
</xsl:element>
</td>
</tr>
</xsl:element>
</table>
</td></tr>
</xsl:for-each>
<tr id="onderbalk">
<td colspan="4">
<xsl:text disable-output-
escaping="yes"><xsl:text disable-output-escaping="yes">
&amp;nbsp; </xsl:text></xsl:text>
</td>
</tr>
</table>
</div>
</xsl:element>
50
</xsl:element>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function tussenXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/RefNrVakNr.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
$xsl = $processor->transformToXML($xmldocument);
}
function outputRefXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/Referentiewerken.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
zetVoorwaarde();
vakdetails();
xslRefSamenstellen();
tussenXSLT();
outputRefXSLT();
?>
</body>
</html>
51
Bijlage G: Code van de referentiewerkdetails detailRef.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cursusbibliotheek</title>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8" />
<link rel="stylesheet" type="text/css" href="Stylesheet.css" />
</head>
<body>
<?php
$xsl;
$RefNr;
$processor = new XSLTProcessor();
// zetVoorwaarde() ontvangt het nummer van het opgevraagde
referentiewerk.
function zetVoorwaarde() {
global $RefNr;
$RefNr = $_GET["RefNr"];
}
//De functie xslSamenstellen() zorgt voor de xsl die de gegevens van
het referentiewerk uit Referentiewerken.xml haalt.
function xslSamenstellen() {
global $RefNr;
global $xsl;
$xsl = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<div id="begintekst">
<h2>Details</h2>
<a href="javascript:history.go(-1)"
title="Terug">Terug</a>
</div>
<div id="Referentiewerk">
<xsl:for-each
select="dataroot/Referentiewerken[RefNr='$RefNr']">
<div id="detailtabel">
<h3>Referentiewerkgegevens:</h3>
<table>
<tr id="oneven">
<td style="width:120px">Titel:</td>
<td style="width:400px">
<xsl:value-of select="Titel"/>
</td>
</tr>
52
<tr id="even">
<td>Auteur:</td>
<td>
<xsl:value-of select="Auteur"/>
</td>
</tr>
<tr id="even">
<td>Uitgever:</td>
<td>
<xsl:value-of select="Uitgever"/>
</td>
</tr>
<tr id="oneven">
<td>ISBN:</td>
<td>
<xsl:value-of select="ISBN"/>
</td>
</tr>
<tr id= "even">
<td>LCNR:</td>
<td>
<xsl:value-of select="LCNR"/>
</td>
</tr>
<tr id="oneven">
<td>Aleph-nummer:</td>
<td>
<xsl:value-of select="Aleph-nummer"/>
</td>
</tr>
<tr id="even">
<td>Plaatsnummer:</td>
<td>
<xsl:value-of select="Plaatsnr"/>
</td>
</tr>
<tr id="oneven">
<td>Publicatiedatum:</td>
<td>
<xsl:value-of select="Publicatiedatum"/>
</td>
</tr>
<tr id="even">
<td>Editie:</td>
<td>
<xsl:value-of select="Editie"/>
</td>
</tr>
<tr id="oneven">
<td>Aanwezig</td>
<td>
<xsl:if test="Aanwezig=-1">
53
Ja
</xsl:if>
<xsl:if test="Aanwezig=0">
Nee
</xsl:if>
</td>
</tr>
</table>
</div>
<h3>Dit werk zoeken ...</h3>
<table cellpadding="10">
<tr id="oneven">
<td> op ISBN</td>
<td>
<xsl:element name="a">
<xsl:attribute
name="href">
<xsl:value-of
select="concat('http://search.ugent.be/meercat/x/all?q=', translate(ISBN, '
-',''))"/>
</xsl:attribute>
in UGent
Bibliotheek
</xsl:element>
</td>
<td>
<xsl:element name="a">
<xsl:attribute
name="href">
<xsl:value-of select="concat('http://www.google.com/search?tbm=bks',
'&', 'q=isbn:' ,translate(ISBN, ' -',''))"/>
</xsl:attribute>
met Google
</xsl:element>
</td>
</tr>
<tr id="even">
<td>op Auteur en Titel</td>
<td>
<xsl:element name="a">
<xsl:attribute
name="href">
<xsl:value-of
select="concat('http://search.ugent.be/meercat/x/all?q=', 'author:',
Auteur, ' ', 'title:', Titel) "/>
</xsl:attribute>
in UGent
Bibliotheek
</xsl:element>
</td>
<td>
<xsl:element name="a">
<xsl:attribute
name="href">
54
<xsl:value-of select="concat('http://www.google.com/search?tbm=bks',
'&', 'q=', Auteur, ' ', Titel)"/>
</xsl:attribute>
met Google
</xsl:element>
</td>
</tr>
<tr id="oneven">
<td>op plaatsnummer </td>
<td colspan="2">
<xsl:element name="a">
<xsl:attribute
name="href">
<xsl:value-of
select="concat('http://search.ugent.be/meercat/x/all?q=location:',
Plaatsnr)" />
</xsl:attribute>
in
Ugentbibliotheek
</xsl:element>
</td>
</tr>
</table>
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function outputXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/Referentiewerken.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
//hierna de functies die bij het referentiewerk de cursussen die ervan
gebruik maken, vinden
function xslRefSamenstellen() {
global $xsl;
global $RefNr;
$xsl = <<<heredoc
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
55
<xsl:template match="/">
<xsl:element name='xsl:stylesheet'>
<xsl:attribute name='version'>1.0</xsl:attribute>
<xsl:element name="xsl:key">
<xsl:attribute name="name">uniqueselect</xsl:attribute>
<xsl:attribute name="match">webdata</xsl:attribute>
<xsl:attribute name="use">NR</xsl:attribute>
</xsl:element>
<xsl:element name='xsl:template'>
<xsl:attribute name='match'> / </xsl:attribute>
<br/>
<div id="Vakken">
<h3>Vakken die dit werk als referentiewerk
hebben:</h3>
<table>
<xsl:for-each
select="dataroot/RefNrVakNr[RefNr='{$RefNr}']">
<xsl:element name='xsl:for-each'>
<xsl:attribute
name='select'>dataroot/webdata[contains(NR, '<xsl:value-of
select="Nr"/>')and (generate-id(.) = generate-id(key('uniqueselect',
NR)[1]))]</xsl:attribute>
<tr><td>
<table>
<tr id=”even”>
<td>
<form method="get"
action="detail.php">
<xsl:element
name="input">
<xsl:attribute
name="type">hidden</xsl:attribute>
<xsl:attribute
name="name">NR</xsl:attribute>
<xsl:attribute
name="value">
<xsl:value-of select="Nr"/>
</xsl:attribute>
</xsl:element>
<input type="image"
src="afbeeldingen/Details.gif" alt="Bekijk Details"/>
</form>
</td>
<td style="width:420px">
56
<b>
<xsl:element name='xsl:value-of'>
<xsl:attribute
name="select">Vak</xsl:attribute>
</xsl:element>
</b>
</td>
</tr>
<tr id=”oneven”>
<td></td>
<td>Code:
<xsl:element name='xsl:value-of'>
<xsl:attribute
name="select">NR</xsl:attribute>
</xsl:element>
</td>
</tr>
</table>
</td></tr>
</xsl:element>
</xsl:for-each>
</table>
</div>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
heredoc;
}
function tussenXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/RefNrVakNr.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
$xsl = $processor->transformToXML($xmldocument);
}
function outputRefXSLT() {
global $xsl;
global $processor;
$xsldocument = new SimpleXMLElement($xsl);
$xmldocument = new DOMDocument();
$xmlLink = 'xml/webdata.xml';
$xmldocument->load($xmlLink);
$processor->importStylesheet($xsldocument);
echo $processor->transformToXML($xmldocument);
}
57
zetVoorwaarde();
xslSamenstellen();
outputXSLT();
xslRefSamenstellen();
tussenXSLT();
outputRefXSLT();
?>
</body>
</html>
58
Referenties
[1] UGent, “OASIS | OASIS-project”, 02-aug-2011. [Online]. Available:
http://project.oasis.ugent.be/. [Accessed: 03-aug-2011]. [2] W3C, “Extensible Markup Language (XML) 1.0 (Fifth Edition)”, 26-nov-2008. [Online]. Available:
http://www.w3.org/TR/2008/REC-xml-20081126/. [Accessed: 06-aug-2011]. [3] W3C, “Extensible Markup Language (XML)”, 1996. *Online+. Available:
http://www.w3.org/TR/WD-xml-961114.html. [Accessed: 06-aug-2011]. [4] ISO, “8879:1986 Information processing -- Text and office systems -- Standard Generalized
Markup Language (SGML)”. 1986. [5] W3C, “Tags used in HTML”, 1992. *Online+. Available: http://www.w3.org/History/19921103-
hypertext/hypertext/WWW/MarkUp/Tags.html. [Accessed: 07-aug-2011]. [6] W3C, “XML Syntax”. *Online+. Available: http://www.w3schools.com/xml/xml_syntax.asp.
[Accessed: 07-aug-2011]. [7] Mike Johnston, “What is a CMS? |”, CMS Critic, 28juli-2010. [Online]. Available:
http://www.cmscritic.com/what-is-a-cms/. [Accessed: 08-aug-2011]. [8] Symphony, “Symphony Server Requirements”. *Online+. Available: http://symphony-
cms.com/#requirements. [Accessed: 01-aug-2011]. [9] Symphony, “Symphony Concepts: Page Templates”. *Online+. Available: http://symphony-
cms.com/learn/concepts/view/page-templates/. [Accessed: 10-aug-2011]. [10] Symphony, “Symphony Concepts: Data Sources.” *Online+. Available: http://symphony-
cms.com/learn/concepts/view/data-sources/. [Accessed: 08-aug-2011]. [11] W3C, “The Extensible Stylesheet Language Family (XSL)”. *Online+. Available:
http://www.w3.org/Style/XSL/. [Accessed: 10-aug-2011]. [12] W3C, “XML Path Language (XPath)”. *Online+. Available: http://www.w3.org/TR/xpath/.
[Accessed: 10-aug-2011]. [13] António Mota, “difference xsl xslt - Re: Difference between XSL and XSLT”, 10-feb-2006. [14] Benoît Marchal, “Discover the Wonders of XSLT: XSLT Quirks”, 21-mei-2004. [Online].
Available: http://www.developer.com/xml/article.php/3357231#Rewriting. [Accessed: 08-aug-2011].
[15] Symphony, “‘Symphony API Documentation’”, 03-aug-2011. [Online]. Available: http://symphony-cms.com/discuss/blog/entry/symphony-api-documentation/. [Accessed: 08-aug-2011].
[16] The PHP Group, “PHP: XSLTProcessor - Manual”. *Online+. Available: http://php.net/manual/en/class.xsltprocessor.php. [Accessed: 11-aug-2011].
[17] The PHP Group, “PHP: XSL Installation - Manual”, 05-aug-2011. [Online]. Available: http://www.php.net/manual/en/xsl.installation.php. [Accessed: 11-aug-2011].
[18] The PHP Group, “PHP: XSL Requirements - Manual”. *Online+. Available: http://www.php.net/manual/en/xsl.requirements.php. [Accessed: 11-aug-2011].
[19] The PHP Group, “PHP: XSLTProcessor::__construct - manual”. *Online+. Available: http://www.php.net/manual/en/xsltprocessor.construct.php#91296. [Accessed: 11-aug-2011].
[20] The PHP Group, “PHP: XSLTProcessor::transformToXML - Manual”. *Online+. Available: http://www.php.net/manual/en/xsltprocessor.transformtoxml.php. [Accessed: 11-aug-2011].
[21] W3C, “XSLT <xsl:output> Element”. *Online+. Available: http://www.w3schools.com/xsl/el_output.asp. [Accessed: 14-aug-2011].
[22] Mukul Gandhi, “XSLT grouping techniques”, 27-dec-2009. [Online]. Available: http://gandhimukul.tripod.com/xslt/grouping.html. [Accessed: 12-aug-2011].
59
[23] Steve Muench, “Re: grouping (was: if or template?)”, 08-mei-2000. [Online]. Available: http://www.biglist.com/lists/xsl-list/archives/200005/msg00270.html. [Accessed: 12-aug-2011].
60