Till startsidan för Jonas Webresurs

Elementdeklarationer i Xml

1. Inledning

Den här sidan berättar mer om hur man deklarerar element. Jag kommer att gå igenom de viktigaste kommandona för den som vill kunna skapa en användbar DTD. Sidan bygger självklart vidare på de tidigare sidorna i den här sektionen.

2. Elementtyper

När man deklarerar element måste man först och främst tala om vilket innehåll det har. Innehållet bestämmer vilken slags element det är.

I mitt exempel från förra sidan använde jag enbart två slags innehåll, dels andra element och dels textinnehåll eller "PCDATA#".

Element:
<!ELEMENT latar (namn, langd)>

Text:
<!ELEMENT namn (#PCDATA)>

Innehållet i ett element styr alltså elementtypen. Förutom dessa två finns även ytterligare ett par, dels tomma (empty) och dels valfria (any).

Tomma element är sådana som saknar element- eller textinnehåll (de kan dock innehålla attribut). Tomma element är inte vanliga, men förekommer i olika sammanhang. Från Html känner vi ju <br>, alltså en radbrytning. Ett sådant element skulle vi kunna deklarera så här:

<!ELEMENT br EMPTY)>

Den fjärde typen av element skapades förmodligen från början för att underlätta utvecklingsarbetet med en DTD. Det deklareras så här:

<!ELEMENT musik ANY)>

Man säger här att elementet kan innehålla vad som helst. Detta sätt att deklarera ett element på är dock inte särskilt lämpligt, eftersom själva poängen med Xml är att definiera elementens innehåll.

3. Kardinalitet

Överskriften till det här avsnittet skulle lika gärna ha kunnat vara "Elementdata", eftersom det jag nu skall skriva om handlar om hur data förekommer i en viss elementtyp. Vi har redan stött på detta på förra sidan, i följande exempel:

<!ELEMENT latar (namn*, langd*)>

Här berättar stjärnan att elementen <namn> och <langd> kan förekomma flera gånger i dokumentet.

På engelska pratar man om sådana kommandon som "cardinality indicators". Kardinalitet skulle man kunna kalla det på svenska. Uttrycket används då man beskriver den ordning som olika data har. I Xml är kardinalitet mer exakt ett sätt att tala om hur många gånger ett element förekommer i en deklaration.

Följande indikatorer finns:

* (stjärna)
Elementet förekommer mellan ingen och ett obegränsat antal gånger. Exemplet ovan visar hur det ser ut i deklarationen.

? (frågetecken)
Elementet får förekomma ingen eller högst en gång:

<!ELEMENT cd (artist*, inspelningsstudio?, genre*)>

+ (plustecken)
Elementet måste förekomma minst en gång och får finnas obegränsat antal gånger:

<!ELEMENT artist (fornamn+, efternamn+)>

(inget)
Elementet måste förekomma en gång, men får inte finnas fler gånger.

<!ELEMENT cd (serienummer, artist*, genre*)>

Vilken av dessa man väljer beror självklart på vilken data man skriver in i sitt dokument. Eftersom <namn> och <langd> förekommer flera gånger väljer jag antingen en stjärna eller ett frågetecken. Men i andra dokument kan andra indikatorer passa bättre.

Vårt exempel anger att elementen <namn> och <langd> skall förekomma i elementet <latar>. Men när vi skrev deklarationen angav vi också att de måste förekomma i en viss ordning i dokumentet. Kommatecknet i definitionen är det som styr detta:

<!ELEMENT latar (namn*, langd*)>

Koden måste sedan skrivas:

<latar>
   <namn>
   <langd>
</latar>

Skulle vi byta ordning på elementen:

<latar>
   <langd>
   <namn>
</latar>

...kommer vi att få upp ett felmeddelande, eftersom koden då bryter mot vår DTD.

Vad gör vi då om vi vill ange att blott ett av elementen kommer att finnas med? Här använder man ett lodstreck (|). Tecknet heter "pipeline" på engelska och har teckenkod &#124;:

<!ELEMENT gender (man | kvinna)>

Här säger vi att elementet för kön, <gender>, kommer att ha antingen <man> eller <kvinna>, men inte båda. Detta kallas inom logiken för ett exkluderande eller, till skillnad från då man säger att man eller kvinna eller båda kan förekomma. Det senare kallas följaktligen för ett inkluderande eller, men förekommer inte i Xml.

Skriver man så här:

<!ELEMENT gender (man* | kvinna*)>

säger man att <man> eller <kvinna> kommer att finnas med, antingen ingen eller flera gånger. Det känns kanske som ett konstigt sätt att uttrycka det på, men det är så logiken fungerar i en DTD!

Man kan också kombinera olika uppsättningar av element och indikatorer:

<!ELEMENT upphovsland (svensk | engelsk | amerikansk)>

Elementet <upphovsland> kommer alltså att rymma antingen <svensk>, <engelsk> eller <amerikansk>.

<!ELEMENT musik (artist | (fornamn, efternamn))>

Här säger vi att elementet <musik> antingen kommer att innehålla elementet <artist> eller båda elementen <fornamn> och <efternamn>.

Man kan även uttrycka kardinalitet på hela uttrycket:

<!ELEMENT musik (artist | (fornamn, efternamn)*)>

som säger att elementet <musik> antingen kommer att innehålla elementet <artist> eller ingen/många av båda elementen <fornamn> och <efternamn>. Men detta är inte detsamam som följande:

<!ELEMENT musik (artist | (fornamn*, efternamn*))>

eftersom vi här visserligen säger att <artist> eller det som finns innanför parentesen måste förekomma. Men av båda elementen <fornamn> och <efternamn> kan de var för sig förekomma ingen eller flera gånger.

Likaså är följande definition något annat:

<!ELEMENT musik (artist | (fornamn, efternamn))*>

Här säger vi att <musik> kan innehålla en eller flera förekomster av <artist> eller både <fornamn> och <efternamn>.

Man kan också skapa element med blandat innehåll. Man kan t.ex skriva:

<!ELEMENT namn (#PCDATA | b)>

Elementet <namn> kan här användas antingen med ett rent textinnehåll, men också med ett underelement <b>, som t.ex kan vara fet stil för en viss text. <b> kommer då att definieras för sig:

<!ELEMENT b (#PCDATA)>


Den här sidan är en del av Jonas Webresurs - www.jonasweb.nu - copyright © 1998-2011