XML struktur
Bibelen
La oss tenke oss at vi ønsker å lage en XML-struktur av bibelen. Hensikten kan være at vi ønsker å lage et vevsted for raske oppslag eller at vi ønsker å lage utskrifter av vers, bøker eller andre utdrag. Altså et generelt og litt upresist formål.
Hvis vi tar utgangspunkt i den strukturen som finnes i bibelen, finner vi noe slikt:
Vi kan lage en XML-struktur som avbilder dette direkte, skissert slik:
<?xml version="1.0" encoding="utf-8"?> <bibelen> <gamle_testamente> ... </gamle_testamente> <nye_testamente> <evangeliene> <johannes>...</johannes> <markus>...</markus> <matteus>...</matteus> <lukas> <kap> <vers>...</vers> <vers>...</vers> ... </kap> </lukas> <johannes_åpenbaring> </johannes_åpenbaring> osv... </evangeliene> </nye_testamente> </bibelen>
Dette er neppe særlig lurt. Vi får en grisete dokumentbeskrivelse og den koden vi må skrive for å lete i og manipulere strukturen må forholde seg til en rekke "spesialtilfeller". Det første vi bør gjøre er å generalisere, det vil si finne en generell struktur som kan bære all informasjonen. Kanskje vi kan skissere det slik:
I tillegg til denne grovstrukturen må vi hekte opp de aktuelle navnene enten som elementer under de respektive elementene (testamente, grupp, bok) eller vi må angi navnet som egenskaper, attributter. Nummerering av kapitler og vers følger av elementets plass i barneflokken.
Element eller attributt? er en stadig tilbakevendende problemstilling. Det finnes neppe noe allment svar på dette, men jeg vil prøve ut et resonnement.
Det går i korthet ut på at jeg lokaliserer det "viktigste" elementet. I dette tilfellet velger jeg bok.
Argumenter for å velge bok er for det første at det er det øverste elementet som har en ens substruktur. Gruppe er tvilsom fordi ikke alle bøker er grupperte. Vi må da innføre kunstige grupper med kun en bok. For det andre tror jeg at bok vil være et naurlig fokus for avsøking og ekstrahering. Alt som er over dette valgte elementet, unntatt rotelementet, angir jeg som attributter.
Konsekvensen av dette blir:
En XML-skisse blir slik:
<?xml version="1.0" encoding="utf-8"?> <bibelen> <bok navn="Lukas evangelium" testamente="NT" gruppe="evangeliene"> <kap> <vers> </vers> </kap> </bok> </bibelen>
Hvis vi skal karakterisere denne øvelsen kan vi si at vi har "brettet" strukturen rundt det fokuserte elementet og plassert elementene over, untatt rotelementet, som attributter.
Nå er det ikke sikkert at vi stopper her. Det kan finnes argumenter for å innføre andre elementer og attributter av årsaker som henger sammen med den funksjonaliteten vi planlegger. En forsker på bibeltekster vil definitvt ha behov for innføre en rekke andre egenskaper ved bøkene.
Det som er gjort ovenfor er ikke på noen måte noen oppskrift på hvordan en skal gå fram ved design av en XML-struktur. Det er bare ett av mange mulige resonnementer som kan prøves ut.
Alpint
La oss tenke oss at vi ønsker å lage en oversikt over resultater i internasjonale alpinrenn. Hvis vi betrakter problemet "ovenfra" vet vi at slike renn arrangeres i mange kategorier. Vi konsentrerer oss om Olymiader(OL), Verdensmesterskap(VM) og World Cup(WC). For enkelhets skyld nøyer vi oss med slalom og utfor. Vi kan da tenke oss en slik struktur, hvis vi som sagt ser det "ovenfra":
Igjen har vi en struktur som neppe bør avbildes direkte. Vi må søke fokus i materialet. Det resonnementet vi førte for bibelen er litt vanskeligere å få øye på. Vi må tro at siden det er ønskelig å sammenligne resultater fra alle de tre typene arrangementer, så er det selve arrangementet eller rennet som må stå i fokus. Vi kan da i hvert fall delvis gjennomføre resonnementet fra bibel-eksempelet og si at arrangemenetstypen (OL, VM, WC) blir en egenskap ved et skirenn. Det samme kan vi gjøre med nodene tid og sted. En "bretteøvelse" lik den vi gjorde i bibeleksempelet bringer oss til følgende struktur:
Det gir oss fire typer renn: slalom/menn, slalom/kvinner, utfor/menn og utfor/kvinner. Her kan vi tenke på flere forskjellige måter:
- Det er trolig ikke slik at vi skal sammenligne menn og kvinner i de programmene som skal bruke denne informsjonen. Vi kan kanskje skille de to helt fra hverandre og lage en fil for alpint-menn og en for alpint-kvinner.
- Strukturen for de to typene renn (slalom og utfor) er litt forskjellige siden slalom består av to omganger. Vi kan derfor kanskje skille slalom og utfor som separate barn under alpin.
- Vi kan se bort fra forskjellen i struktur mellom slalom og utfor og si at renntypen skal avgjøre om tid2 er signifikant eller ikke.
Hvis vi velger det siste alternativet og lar kvinner og menn opptre i samme fil, kan vi ende opp med følgende:
<?xml version="1.0" encoding="utf-8"?> <alpin> <skirenn type="WC" tid="2001" sted="Wengen" kjønn="menn" gren="utfor"> <deltager> <navn>Kjuus</navn> <Nasjon>Norge</Nasjon> <tid1>130.012</tid1> <td2>na</td2> </deltager> ... </skirenn> ... </alpin>
Nærmere ettertanke kan kanskje lede oss på andre spor ? Tenk gjennom noen alternativer.
Olympiade
La oss anta en XML-fil som inneholder sprintresultater for de seneste sommerolympiadene. Denne fila er bygd opp slik:
<?xml version="1.0" encoding="utf-8"?> <IOC> <OlympicGame place="Barcelona" year="1992"> <event dist="100m"> <athlet> <name>Dennis Mitchell</name> <nation>USA</nation> <result>10.04</result> </athlet> ... </event> <event dist="200m"> ... </event> ... </OlympicGame> <OlympicGame place="Atlanta" year="1996"> ... </OlympicGame> ... </IOC>
Dersom vi skal følge resonnementet som er brukt under alpineksempelet ovenfor vil vi få noe slikt.
<?xml version="1.0" encoding="utf-8"?> <IOC> <event dist="100m" place="Sidney" year="2000"> <athlet> <name>Maurice Greene</name> <nation>USA</nation> <result>9.87</result> </athlet> ... </event> <event dist="200m" place="Sidney" year="2000"> ... </event> ... </IOC>
Overgangen fra den ene strukturen til den andre kan vi enkelt realisere med en transformasjon i XSLT. XSLT er nærmere beskrevet på nettstedet XSLT. Transformasjonen kan se slik ut:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" doctype-system="olympreorg.dtd" encoding="UTF-8"/> <xsl:template match="/"> <IOC> <xsl:apply-templates select="/IOC/OlympicGame/event"/> </IOC> </xsl:template> <xsl:template match="event"> <xsl:element name="event"> <xsl:attribute name="dist"> <xsl:value-of select="@dist"/> </xsl:attribute> <xsl:attribute name="place"> <xsl:value-of select="ancestor::OlympicGame/@place"/> </xsl:attribute> <xsl:attribute name="year"> <xsl:value-of select="ancestor::OlympicGame/@year"/> </xsl:attribute> <xsl:apply-templates select="athlet"/> </xsl:element> </xsl:template> <xsl:template match="athlet"> <xsl:copy-of select="."/> </xsl:template> </xsl:stylesheet>
Dette demonstrerer noe av den fleksibiliteten vi har når det gjelder å restrukturere XML-data.