Att definiera en elementtyp innebär att först identifiera den. Identifieringen görs genom att den namnges. Sedan definieras de regler som ska gälla för den typ av element, dess förekomst, dvs;
Elementet stycke kan till exempel förekomma ett obegränsat antal gånger i ett dokument. Varje förekomst uppmärks på samma sätt, dvs alla stycken markeras enligt samma regler.
Elementtyp: Komponent av hierarkisk struktur definierad av DTD.
Ett namn skapas av vanliga bokstäver och siffror. Namnen får dock inte börja på bokstavs-kombinationen xml som är reserverad. Det kan även innehålla bindestreck, understrykningar, punkter och kolon. Med kolon bör man dock vara försiktig då de är (mer eller mindre) reserverade för XMLs ändamål, t ex för att definiera namnrymder som kommer att beskrivas längre fram.
En elementdeklaration för rotelementet artikel ser ut så här:
<!ELEMENT artikel (regler för artikel)>
I "regler för artikel" definieras vilka andra element (barn) som elementet artikel får innehålla och hur dessa element får förekomma, dvs som vem följer vem och hur många gånger. Det kallas för innehållsmodell (content model).
<!ELEMENT artikel (innehållsmodell)>
Det finns fem elementtyper i dokument av typen artikel: artikel, titel, skribent, rubrik, stycke. Med tanke på att fler artiklar kommer att struktureras och även att artiklar från andra skribenter kanske kommer att läggas till, kan det vara lämpligt att redan nu börja tänka på den framtida databasen och sökmöjligheter.
Elementen titel och skribent har egentligen inte så mycket att göra med rubrik och stycke. Därför kan en uppdelning göras; en del innehållande information om själva dokumentet, såsom skribent och titel, och en del innehållande själva artikeln, textmassan.
Den första delen kan kallas för meta-info. Senare kan en annan information läggas till den, t ex när artikeln skrevs, publicerades eller i vilken tidskrift. Den andra delen kan kallas för body.
Enligt en sådan uppdelning måste elementen titel och skribent vara barn till elementet meta-info. Det bestäms även att de måste förekomma i en speciell ordning; först titel, sedan skribent. Elementen rubrik och stycke få vara barn till body. Dokumentet kommer att se ut så här:
| artikel1.xml |
|---|
|
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> <artikel> <body> |
Om dokumentet ska vara giltigt måste det validera mot en DTD. DTD skrivs som en vanlig textfil. Elementtypen definieras en gång. Om elementtypen skulle definieras fler än en gång gäller bara den sistskrivna deklarationen, de andra ignoreras. Elementen kan definieras i valfri ordning. Men det tycks vara logiskt att gå uppifrån och nedåt i den hierarkiska strukturen. DTDn för artikel ser ut så här:
| artikel.dtd |
|---|
|
<!ELEMENT artikel (meta-info, body)> |
DTDn innehåller sju elementtyps-deklarationer. Deklarationerna identifierar rotelementet samt alla de element som rotelementet får innehålla inklusive regler för dess förekomst (innehållsmodellen). M.a.o. definierar artikel.dtd dokumenttypen artikel.

Sekvensoperatorer (, | &) talar om i vilken ordning elementen får förekomma. Observera att inom ramar av samma innehållsmodell får operatorerna inte blandas ihop. I fall av förekomst av olika sekvensoperatörer ska elementen grupperas. Mer om detta lite längre ner i avsnittet "Elementgruppering".
<!ELEMENT artikel (meta-info, body)> <!ELEMENT meta-info (titel, skribent+)> <!ELEMENT titel (#PCDATA)*> <!ELEMENT skribent (#PCDATA)*> <!ELEMENT body (rubrik | stycke)*> <!ELEMENT rubrik (#PCDATA)*> <!ELEMENT stycke (#PCDATA)*> |
|
Antalsoperatorer (+ * ?) talar om hur många gånger elementen får förekomma.
<!ELEMENT artikel (meta-info, body)> <!ELEMENT meta-info (titel, skribent+)> <!ELEMENT titel (#PCDATA)*> <!ELEMENT skribent (#PCDATA)*> <!ELEMENT body (rubrik | stycke)*> <!ELEMENT rubrik (#PCDATA)*> <!ELEMENT stycke (#PCDATA)*> |
|
Observera: #PCDATA (teckendata) listas alltid först i gruppen och att en grupp innehållande #PCDATA måste betecknas med en *-indikator, dvs noll gång eller flera gånger.
Antalsindikatorer i grupper:
Antalsindikatorer i grupper placeras till höger om gruppen - om samma regler gäller hela gruppen. Om olika regler gäller placeras antalsindikatorn till höger om varje individuellt element.
Står antalsindikatorn precis till höger om elementet gäller regeln bara det elementet. I (titel, skribent+) får endast skribent repeteras.
(titel, skribent+)
Element grupperas om samma regler gäller för två eller fler element. Till grupperingar används parenteser. I (rubrik | stycke)* gäller samma regler för både rubrik och stycke. Finns det bara ett element i innehållsmodellen behövs det inga parenterser.
(rubrik | stycke)*
stycke*
Varje element har sin egen antalsidikator när olika förekomstregler gäller.
(titel?, skribent+)
En sammanfattning av hur elementen styrs av ordningsoperatorer och antalsindikatorer kan illustreras på följande sätt (g = gång):
| Element | Måste innehålla | Kan innehålla | Följd av | Förekommer i |
|---|---|---|---|---|
| artikel | meta-info 1g och body 1g |
meta-info 1:a body 2:a |
inget - rotelement | |
| meta-info | titel 1 g och skribent 1/fler g |
titel 1:a skribent 2:a |
artikel | |
| titel | #PCDATA 0/fler g | meta-info | ||
| skribent | #PCDATA 0/fler g | meta-info | ||
| body | rubrik 0/fler g eller stycke 0/fler g |
rubrik 0/fler g eller stycke 0/fler g |
valfri | artikel |
| rubrik | #PCDATA 0/fler g | body | ||
| stycke | #PCDATA 0/fler g | body |
Observera:
rubrik och stycke måste både och kan förekomma i body. Detta beror på den valfrihet ordningsoperatorerna | ger. I praktiken betyder det att ett av dem måste förekomma i body medan det andra kan.
#PCDATA "kan" och "måste" inte förekomma i rubrik. Om #PCDATA var tvungen att förekomma i rubrik måste ju även rubrik förekomma och det finns inget krav på det. Samma gäller för stycke. Det kan finnas artiklar innehållande enbart rubriker.
Det finns en enkel förklaring till varför stycke inte behöver följa efter rubrik utan är dess bror (eller syster). Det är långt ifrån alla artiklar som börjar med en rubrik. De flesta brukar faktiskt börja med ett stycke, t ex en ingress.

Familens artikel familjeträd
Enligt DTDn kan både rubrik och stycke förekomma noll gång eller fler gånger. De kan även förekomma i en valfri följd. Till höger visas tre exempel på deras möjliga förekomst.

Familjeträdet kan byggas på i oändlighet utan att för den delen påverka dokumentets logiska struktur. Vid behov kan nya element läggas till (t ex) skribent och titel.

I SGML-elementdeklarationer expanderar strängen regler för elementtyp till markeringsregler och innehållsmodell. Till exempel:
<!ELEMENT artikel (regler för artikel)>
expanderar till
<!ELEMENT artikel markeringsregler (innehållsmodell)>
exempelvis
<!ELEMENT artikel - - (innehållsmodell)>
SGML tillåter fyra olika markeringssätt. Det beror dels på att vissa taggar är valfria och tillåts s.k. minimanization, dels på brist på sluttaggar hos tomma element, dvs sådana element som saknar innehåll, till exempel radbrytningar. I XML ska början på alla element indikeras av en starttag och slutet med en sluttagg. (Se avsnittet Välutformade dokument.) Då markeringsregler är bestämda i förvägg behövs inga markeringsregler i elementdeklarationer.
Följande markeringsregler gäller i SGML. Första tecknet representerar starttaggen och det andra sluttaggen.
| - - | Båda obligatoriska |
| - 0 | Starttagg obligatorisk, sluttagg valfri (O står för optional) |
| 0 0 | Båda valfria |
| - O EMPTY | Tomt element, starttagg obligatorisk, sluttagg förbjuden (saknas) |
I XHTML, i likhet med XML, specificeras inga markeringsregler. De är kända på samma sätt som i XML. I HTML 4 Strict däremot finns det följande exempel.
| A (ankare) | <!ELEMENT A - - (%inline;)* -(A) > båda obligatoriska |
| P (stycke) | <!ELEMENT P - O (%inline;)* > starttagg obligatorisk, sluttagg optionell |
| BODY | <!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL)> båda optionella |
| IMG (bild) | <!ELEMENT IMG - O EMPTY > starttagg obligatorisk, sluttagg förbjuden. Tomt element |
Element är den minsta strukturella delen i ett XML-dokument. Det finns två typer av element: behållare och tomma element. Den första gruppen "behåller" något innehåll medan den andra saknar innehåll.
De flesta element är s.k. behållare, t ex ovannämnda stycke. De innehåller något, t ex text:
<stycke>jag är innehåll i elementet stycke och omges av ett par taggar, en starttagg som talar om när jag börjar och en sluttagg som talar om när jag slutar</stycke>
Det finnas dock ett antal elementtyper som saknar innehåll. Två exempel på sådana element är HTMLs <br>, radslut, och <img>, bild. Elementen innehåller varken radslut eller bild i sig själv, utan markerar det ställe där radbrytningen eller bilden ska sättas in. Ett annat exempel, också taget från HTML, är elementet META. Det tomma elementet innehåller information avsett för olika applikationer, t ex sökmotorer, och är inte en del av själva dokumentet eller snarare sagt dess synliga del.
Om en elementtyp är tom måste det definieras specifikt i dess elementdeklaration. Om det inte görs betraktas elementtypen som behållare. För att definiera en elementtyp för tom används nyckelordet EMPTY.
<!ELEMENT img EMPTY>
<!ELEMENT br EMPTY>
<!ELEMENT meta EMPTY>
I SGML saknar tomma element en sluttagg. Man kan väl säga att deras enda tagg är både start- och sluttagg. XML kräver att alla element, och det inkluderar även tomma element, som börjar med en starttagg även ska ha en matchande sluttagg. Därför markeras slutet på tomma element med en matchande sluttagg, en s.k. "tomelementstagg" , dvs sluttaggen inkluderas i själva starttaggen. Observera mellanslaget före snedstrecket.
Pga bakåtkompabiliteten kan det vara lite problematiskt att, än så länge, använda sig av den första metoden. Därför rekommenderar man den andra.
Tomma element som stängs med en matchande sluttagg:
<img></img>
<br></br>
Tomelementstagg:
<img />
<meta />
I XML kan varje element definieras som tomt element. Observera dock att tomma element inte syns. De kan användas som ovan, till radbrytningar eller till bildinfogningar, eller för att innehålla attributvärden för "privat bruk".
Om innehållsmodellen innehåller fler än ett element brukar man gruppera elementen. Grupperingssättet beror på hur elementen förekommer, dvs deras ordningsföljd och förekomstantal. Till grupperingar används parenteser. Finns det bara ett element i innehållsmodellen behövs det inga parenteser.
Exempel:
Elementet body kan innehålla bara ett element, avsnitt
<!ELEMENT body avsnitt>
Detta body-element kan innehålla en grupp element. Gruppen kan bestå av elementen avsnitt och stycke.
Dessutom säger innehållsmodellen att body ska följas noll eller fler gånger av antingen avsnitt eller stycke
<!ELEMENT body(avsnitt*| stycke*)>
Då samma regler gäller både avsnitt och stycke kan reglerna tilldelas hela gruppen istället för varje enskilt element.
<!ELEMENT body(avsnitt | stycke)*>
Detta body-element ska följas av avsnitt, som i sin tur ska följas av antingen rubrik eller stycke.
Sekvensoperatorer får inte blandas ihop. Därför måste man gruppera dessa element så att de olika operatorerna inte blandas ihop utan är specifika för gruppen.
Fel
<!ELEMENT body (avsnitt, rubrik | stycke)*>
Rätt
<!ELEMENT body avsnitt*, (rubrik | stycke)*>
Då det samma gäller alla tre elementen kan även reglerna tilldelas hela innehållsmodellen.
<!ELEMENT body (avsnitt, (rubrik | stycke))*>
Detta body-element följs av kapitel som följs av antingen avsnitt eller av element rubrik följt av stycke
<!ELEMENT body (kapitel, avsnitt | (rubrik, stycke))>
Elementet stycke följs av antingen #PCDATA eller betoning. Observera att #PCDATA alltid listas först i gruppen och att en grupp innehållande #PCDATA måste betecknas med en *-indikator, dvs noll gång eller flera gånger.
<!ELEMENT stycke (#PCDATA| betoning)*>
Alla ovannämnda element, samt alla andra element som definieras enligt principen <!ELEMENT elementtyp (innehållsmodell)>, markeras med en starttagg och en sluttagg.
<starttagg>element</sluttagg>
t ex
<stycke>innehåll</stycke>
Tomma element saknar innehåll och därför saknar även deras deklarationer innehållsmodellen.
<!ELEMENT br EMPTY>
<!ELEMENT img EMPTY>
<!ELEMENT meta EMPTY>
Trots att elementet är tomt kan det ändå ha olika egenskaper. Om till exempel elementet meta-info gjordes till tomt element kunde man tilldela det bl a attributet titel och skribent.
<artikel>
<meta-info titel="..." skribent="..." />
<body>
...
</body>
</artikel>
Tomma element markeras med en starttagg och en sluttagg eller med en tomelementstagg. Observera mellanslaget före snedstrecket i tomelementstagg.
<starttagg></sluttagg>
t ex
<br></br>
eller
<br />
ANYRotelementet bok kan innehålla elementen kapitel, avsnitt, rubrik och stycke. Dessa fyra är barn till bok. Om omvänt, är bok förälder till dessa fyra element. Då det inte finns någon krav på hur en bok ska börja kan vart och ett av dessa element följa sin förälder. (Man kanske skulle kunna jämföra dem med fyrlingar?)
Då bok kan innehålla alla element som dessutom kan följa sin respektive förälder i valfri ordning finns det ingen anledning att lista varje barnelement i innehållsmodellen utan samla ihop dem med hjälp av nyckelordet ANY.
Elementet bok följs av något (any) av sina barn i valfri ordning.
<!ELEMENT bok ANY>
Observera att en ANY-innehållsmodell även kan innehålla #PCDATA.
<bok> |
<bok> |
<bok> |
<bok> |
<bok> |
Elementet kapitel kan också innehålla andra element utöver de ovannämnda, till exempel bilder, betonad text eller radbrytning. Samma element kan förekomma i avsnitt, rubrik och stycke. Istället för att skriva ut dem i varje innehållsmodell kan man skapa en entitet av dem.
<!ENTITY %special "bild | betoning | br">
Och sedan inkludera den i innehållsmodellen:
<!ELEMENT rubrik (#PCDATA | %special)*>
<!ELEMENT stycke (#PCDATA | %special)*>
Som när den påträffas kommer att expandera till:
<!ELEMENT rubrik (#PCDATA | bild | betoning | br)*>
<!ELEMENT stycke (#PCDATA | bild | betoning | br)*>
Innehållsmodellen kan byggas upp av endast entiteter. En parser "översätter" entiteterna till de i entitetsdeklarationerna specificerade strängarna.
Exempel från DTD för XHTML 1.0 Strict: <!ELEMENT H1 %Inline;>
Innehållsmodell i elementets H1 (rubrik på nivå 1) är entiteten %Inline. Entiteten definieras som <!ENTITY % Inline "(#PCDATA | %inline; | %misc;)*">. Den innehåller #PCDATA och entiteterna %inline samt %misc som i sin tur innehåller andra entiteter. När alla strängar har bytts ut mot sitt egentliga innehåll kommer H1s innehållsmodell att se ut enligt följande:
<!ELEMENT H1 (#PCDATA | a | br | span | bdo | object | img | map| tt | i | b | big | small| em | strong | dfn | code | q | sub | sup | samp | kbd | var | cite | abbr | acronym | input | select | textarea | label | button | ins | del | script | noscript)*>
Innehållsmodellen och därmed deklarationerna kan vara av fyra typer: barn (children), vilken som helst (any), blandad (mixed) och tom (empty).
| Deklarationen överensstämmer med children när de ingående barnelementen hör till det språk som skapats av uttrycket i innehållsmodellen. | <!ELEMENT body (rubrik | stycke)*> |
| Deklarationen överensstämmer med any när elementtyperna för alla barnelement har deklarerats. | <!ELEMENT bok ANY> |
| Deklarationen överensstämmer med mixed när innehållet består av #PCDATA och barnelement. | <!ELEMENT stycke (#PCDATA | betoning)*> |
| Deklarationen överensstämmer med empty när elementet inte har något innehåll. | <bild EMPTY> |
Textmassan i ett XML-dokument består av teckendata och märkord. All text som inte är märkord är teckendata.
Uppmärkning är semantiskt avgränsade tecken som läggs till data i ett dokument för att representera dess struktur. Det finns fyra olika uppmärkningar: beskrivande (tags), referenser, uppmärkningsdeklarationer och processinstruktioner.