1 Info-books HO35 Toegepaste Informatica Deel 35: XML - XSL Jos Gils Erik Goossens2 Hoofdstuk 5 Het Document Object Model 5.1 Probleemstelling Wanneer...
Probleemstelling Wanneer je de inhoud van een document en de presentatie uiteen wilt houden dan moet het basisdocument dat de te presenteren inhoud bevat goed gestructureerd zijn zodanig dat het later kan opgemaakt worden met een document dat de lay-out beschrijft. Bovendien moet je voorzien dat de structuur van het basisdocument kan aangepast worden zonder dat het document dat de presentatie bevat moet gewijzigd worden. Om deze twee redenen stellen parsers het basisdocument (het XML-document) in het interne geheugen voor onder vorm van een structuur die mogelijk maakt dat elk onderdeeltje van het XML-document kan bereikt worden. Deze interne structuur wordt Document Object Model genoemd.
5.2
Algemeen
5.2.1 Wat is het Document Object Model? XML wordt gebruikt om verschillende soorten informatie, opgeslagen op diverse systemen, voor te stellen onder vorm van documenten. Het accent ligt meestal op het XMLdocument zelf en minder op de data. Deze treden pas op de voorgrond wanneer het document gepresenteerd wordt, vaak op basis van een XSL-document. Het beheer van de data kan gebeuren met het DOM. Het DOM is een API (Application Programming Interface) voor XHTML- en XMLdocumenten. Het is een interne voorstelling van de logische documentstructuur en van de manier waarop een document toegankelijk en manipuleerbaar is. Dankzij het DOM krijgt de programmeur op een eenvoudige manier toegang tot de componenten van een document en kan hij inhoud, attributen en stijl toevoegen, verwijderen en aanpassen. Het DOM maakt het voor programmeurs mogelijk om applicaties te schrijven die werken op alle servers, op alle platforms en met alle browsers. Wanneer programmeurs verschillende programmeertalen nodig hebben hoeven zij hun programmamodel niet te wijzigen. Het DOM is een platform- en taalonafhankelijke interface die het programmeren over verschillende platforms met meerdere talen mogelijk maakt. 5.2.2 Typen Er zijn verschillende DOM-typen: •
DOM Level 1: Het eerste DOM-type, het DOM voor HTML- en XML-documenten, steunt op een voorstelling van het document als een interne boom en maakt het mogelijk om de overeenkomstige hiërarchie te doorkruisen. De gestandaardiseerde manier om een docu-
J. Gils – E. Goossens
xml-xsl
57
ment te bekijken is gebaseerd op deze boomstructuur: door middel van een hiërarchie van tags bouwt de computer een intern model van het document op. Het eerste DOM voor HTML beschreef alleen maar methoden, bijvoorbeeld om toegang te krijgen tot een identifier op naam. Het volgende model voorzag al een geheel van eenvoudig te manipuleren HTML-documenten. Er volgden daarna modellen voor XML-documenten. Deze DOM-modellen voor XML en HTML vormen het DOM Level 1. De specificaties zijn er opzettelijk beperkt tot de methodes die nodig zijn voor het voorstellen en het manipuleren van de structuur en de inhoud van de documenten. •
5.3
DOM Level 2: Dit model is gebouwd op Level 1, maar het beschikt over een aantal nieuwe kenmerken zoals een Stylesheet Object Model. Het is een uitbreiding van DOM Level 1.
Een Document Object Model opstellen Zoals vroeger gezegd is een DOM de interne presentatie van een XML-document in de vorm van een boomstructuur. Vertrekken wij bijvoorbeeld van de volgende DTD (DIAREEKS1.DTD) en een XMLdocument (DIAREEKS1.XML) dat erbij hoort. DIAREEKS1.DTD: Edward Vandewalle">
DIAREEKS1.XML: &Edward; Markup-talen XML &XML;
58
xml-xsl
J. Gils – E. Goossens
Een Document Object Model dat bij deze twee documenten hoort kan schematisch als volgt voorgesteld worden:
Het vertrekpunt, de wortel, is het XML-document. In een boomstructuur wordt gesproken van knopen of nodes. De knoop die als vertrekpunt dient wordt de wortelknoop of root node genoemd. Knopen die rechtstreeks van een andere knoop afhangen worden 'kinderen' of 'kindknopen' genoemd. Kinderen van dezelfde ouderknoop worden broers of zussen (siblings) genoemd. Een knoop op het laagste niveau is een 'blaadje' (leaf node). Hier (DIAREEKS.XML) heeft de wortelknoop drie kindknopen: • xml: de processor-instructie die overeenstemt met de eerste lijn uit het XMLdocument; • Diareeks1.dtd: de verwijzing naar de externe DTD waarmee het XML-document zal moeten overeenstemmen. Deze tweede knoop stemt overeen met de tweede lijn in het XML-document. • Diareeks: het element dat zelf subelementen bevat. Ook de attributen worden in het DOM opgenomen: • Het attribuut Version hoort bij de XML-processor-instructie en heeft als waarde "1.0"; • De attributen duur, tool en bedrijf horen bij het element Diareeks en hebben als waarden "2", "PowerPoint" en "Info-Books". • Een knoop kan subknopen hebben. In dit voorbeeld heeft de knoop Diareeks de subknopen Spreker en tweemaal Onderwerp. De waarden van die elementen zijn "Edward Vandewalle", "Markup-talen" en "XML". Merk op dat interne entities niet in het DOM opgenomen werden. Opdracht 1. Teken het DOM dat bij BLOKKEN2.DTD en BLOKKEN2.XML hoort.
J. Gils – E. Goossens
xml-xsl
59
5.4
Items in een DOM benaderen Via het Document Object Model kan, gebruik makend van programmacode, gezocht worden in het XML-document en kunnen gegevens opgehaald en verwerkt worden. Dit veronderstelt wel dat er een systeem bestaat om deze gegevens te benaderen. Vertrekpunt is het XML-document dat de naam xmlDoc krijgt. Verder zijn op dit ogenblik van belang: • childNodes: de reeks van kindknoop-elementen van een bepaalde knoop; • attributes: de reeks van attributen van een element; • item(i): het zoveelste item in de reeks van kindknopen of attributen; De nummering begint bij 0. • text: de tekstwaarde van een item. Toegepast op het voorbeeldmodel zou je de volgende vragen kunnen stellen en het antwoord zoeken in het DOM: •
Wat is de naam van de spreker? xmlDoc.childNodes.item(2).childNodes.item(0).text
Je vertrekt vanuit het XML-document (XMLDOC)en je neemt item(2) van de kindknopen. Dat is Diareeks (ITEM(0) is XML, ITEM(1) is DIAREEKS1.DTD). Vervolgens neem je ITEM(0) van de kindknopen van Diareeks. Dat is Spreker. Van Spreker neem je ten slotte de tekstwaarde. •
Geef de versie van XML. xmlDoc.childNodes.item(0).attributes.item(0).text
Je vertrekt vanuit het XML-document (XMLDOC) en je neemt ITEM(0) van de kindknopen. Dat is XML. Vervolgens neem je ITEM(0) van de attributen van XML. Dat is de versie. Van VERSION neem je dan de tekstwaarde ("1.0"). •
Met welke tool wordt de diavoorstelling gedaan? xmlDoc.childNodes.item(2).attributes.item(1).text
Je vertrekt vanuit het XML-document (XMLDOC) en je neemt ITEM(2) van de kindknopen. Dat is Diareeks. Vervolgens neem je ITEM(1) van de attributen van Diareeks. Dat is de tool. Van tool neem je dan de tekstwaarde ("PowerPoint").
60
xml-xsl
J. Gils – E. Goossens
Opdrachten 2. Laat het bestand DIAREEKS1.HTML tonen in een browser om te navigeren in het Document Object Model van DIAREEKS1.XML. Bekijk eerst de code van DIAREEKS1.HTML in een tekstverwerker: XML DOM Testpagina <script type='text/javascript'> var xmlDoc; xmlDoc= new ActiveXObject("MSXML.DOMDocument"); xmlDoc.validateOnParse = true; xmlDoc.async = false; xmlDoc.load("Diareeks1.xml");
Naam van de spreker:
xmlDoc.childNodes.item(2).childNodes.item(0).text
XML-versie:
xmlDoc.childNodes.item(0).attributes.item(0).text
Presentatietool:
xmlDoc.childNodes.item(2).attributes.item(1).text
Probeer zelf wat uit:
Hoewel het schrijven van de code op dit ogenblik nog niet aan de orde is overlopen we even de inhoud van het document. In het script in dit XHTML-document wordt een object aangemaakt waarin het document J. Gils – E. Goossens
xml-xsl
61
DIAREEKS1.XML geplaatst wordt: <script> var xmlDoc; xmlDoc= new ActiveXObject("MSXML.DOMDocument"); xmlDoc.validateOnParse = true; xmlDoc.async = false; xmlDoc.load("Diareeks1.xml");
In de tweede regel van het script wordt een ActiveXObject aangemaakt. Een ActiveXObject zorgt ervoor dat een verwijzing naar een 'Automation object' ingesteld wordt. Een Automation object is een object dat beschikbaar gesteld wordt voor andere toepassingen dan deze waarvoor het object oorspronkelijk ontwikkeld werd. MSXML is de naam van de toepassing die het object aanmaakt, DOMDOCUMENT is het objecttype dat aangemaakt wordt, XMLDOC is de variabele waar het nieuwe object aan toegewezen wordt. Concreet: wij willen het XML-document DIAREEKS1.XML als een DOM-document benaderen en maken daarvoor een ActiveXObject dat in de objectvariabele XMLDOC geplaatst wordt. ValidateOnParse is een eigenschap die bepaalt of de parser dit document moet valideren (true: ja, false: nee). Async is een eigenschap die aanduidt of asynchroon downloaden van het bestand (als het
op een server staat) toegelaten is. Asynchroon laden betekent bijvoorbeeld: eerst alle XHTML-tags, daarna alle XML-tags,… De gebruiker heeft ingeval van true geen controle over de manier waarop het bestand geladen wordt. Het laden zelf gebeurt met de methode load. Vervolgens wordt een tabel opgebouwd waarvan de eerste rij uit drie cellen bestaat:
Naam van de spreker:
xmlDoc.childNodes.item(2).childNodes.item(0).text
In de eerste cel komt de naam van de spreker, in de tweede de uitdrukking die de tekstwaarde van de knoop met de naam van de spreker weergeeft. Let vooral op de inhoud van de laatste cel: het gaat hier om een knop die, wanneer erop geklikt wordt, een berichtvenster laat zien waarin de naam van de spreker getoond wordt. De volgende twee rijen (XML-versie en Presentatietool) worden op analoge manier opgebouwd.
62
xml-xsl
J. Gils – E. Goossens
De laatste rij geeft je de mogelijkheid om zelf een uitdrukking in te tikken:
Probeer zelf wat uit:
In de eerste cel komt de tekst 'Probeer zelf wat uit'. De tweede cel heeft TXTDOM als naam en bevat standaard de waarde "xmlDoc.childNodes.item(1).xml".
Je kunt daar ook een andere waarde plaatsen. Bij het klikken op de knop in de derde cel wordt een berichtvenster getoond met daarin de waarde van het aangeduide item in de tweede cel (txtDom.value), eventueel omgezet naar een ander type dan tekst (eval()). Wanneer je DIAREEKS1.HTML laat tonen door een browser dan ziet het scherm er ongeveer als volgt uit:
a. Voorspel wat het effect zal zijn als je op elk van de eerste drie KLIK-knoppen drukt. b. Wat is het resultaat als je xmlDoc.childNodes.item(1).xml in het vak "Probeer zelf wat uit:" invult en op de Klik-knop klikt? c. Wat zal het effect zijn van xmlDoc.childNodes.item(2).xml? d. Door op de KLIK-knoppen te klikken wordt het aangeduide gegeven in een berichtvenster getoond. Tik in het vierde vak "Probeer zelf wat uit:" de expressies die de volgende resultaten in een berichtvenster tonen: • • •
de naam van het bedrijf; de duur van de diareeks; het eerste onderwerp.
e. Welke melding krijg je wanneer je een van de volgende items intikt: - xmlDoc.childNodes -
3. Gebruik BLOKKEN2_DOM.HTML om via een berichtvenster de volgende waarden te doen afdrukken: a. het hele XML-document (BLOKKEN2.XML), behalve de eerste twee lijnen; b. de tekst "Breinaald"; c. de uitleg die staat bij de laatste record. 4. Gebruik BLOKKEN2_EXTERNEDTD_DOM.HTML om via een berichtvenster de volgende waarden te doen afdrukken: a. de naam van de redacteur; b. het type van de bron van de eerste record; c. de volledige tweede regel van het XML-document.
64
xml-xsl
J. Gils – E. Goossens
Besluit Een XML-document wordt door een parser in het computergeheugen weergegeven als een boom die vertrekt van het XML-document zelf (xmlDoc), de wortelknoop. Deze knoop heeft verschillende subknopen waarlangs de gegevens die in het document staan bereikt kunnen worden. Het benaderen van een gegeven in de boom gebeurt aan de hand van een uitgestippeld pad dat doorheen de boom loopt. Via een XHTML-document waarin een programmaatje in JavaScript verwerkt werd kun je laten controleren of een door jou uitgestippeld pad leidt naar een gegeven van het XMLdocument waarop het script toegepast werd.
Wat je moet kennen en kunnen: • •
op basis van een XML-document een schematische weergave van een DOM opstellen; gegevens via het Document Object Model opvragen, gebruik makend van een XHTML-pagina met een programma in een scripttaal.
Opdrachten 5. Maak een DTD-bestand CURRICULUMVITAE.DTD dat aan de volgende vereisten voldoet: a. Het CurriculumVitae van een bedrijf dat aan ontwikkeling doet wordt in een XMLdocument (CURRICULUMVITAE.XML) weergegeven. Alle projecten van alle ontwikkelaars staan erin vermeld. CurriculumVitae is het root-element dat uit minstens 1 Ontwikkelaar bestaat; Per ontwikkelaar worden de volgende gegevens geregistreerd: • Voornaam; • NogVoornamen (optioneel); • Familienaam; • E-Mailadres (optioneel); • Projecten. Per project: - Startdatum; - Einddatum; - Omschrijving; - Een reeks sleutels. b. Plaats enkele records die aan de DTD voldoen in CURRICULUMVITAE.XML. c. Valideer het XML-document en breng indien nodig aanpassingen aan. 6. Gebruik CURRICULUMVITAE.HTML om via een berichtvenster de volgende waarden te doen afdrukken: a. het e-mailadres van de eerste ontwikkelaar; b. de derde sleutel van het eerste project van de eerste ontwikkelaar; c. de startdatum van het tweede project van de eerste ontwikkelaar.