Detta är veckans anteckningar på ämnet DTD:er. Anteckningarna är baserade på övningar och texten i boken New Perspectives on XML, 2nd edition av Patrick Carey.
KAP 3 – DTD – PER JOHANSSON
När ett dokument är färdigmarkerat med taggar och länkar till CSS-filer och annat är det (förutsatt det är korrekt format), ”well-formed”.
Men XML dokument är ofta till för att även kontrollera informationen de lagrar efter vissa regler och definitioner. Därför gör man ofta s.k. DTD – document type definitions – som innehåller dessa regler. De XML som sedan använder DTDs regler blir först ”well-formed” när syntaxen är korrekt men även ”valid” när de följer DTD:n.
En DTD kan användas till:
kontrollera att alla element som krävs är med i dokumentet
förhindra att odefinierade element används
tvinga dokumentet att följa en viss dokumentstruktur
specificera vilka attributvärden som är tillåtna och hur de används
definiera standardvärden för attribut
beskriva hur parsern ska behandla icke-XML och objekt som inte är text
Dokument definitionen anges i XML-dokumentet genom att skriva en s.k. dokument typs deklaration, DOCTYPE-declaration. Denna måste läggas in i prologen på dokumentet efter XML deklarationen och före dokumentets rotelement.
Som i CSS kan man ha interna dokumenttyps deklarationer med .
I externa dokumenttyps definitioner skriver man istället en URI som anropar rätt dokument. Här kan man använda sig av SYSTEM eller PUBLIC. SYSTEM dokument nås exklusivt och kopplas via URI:n. PUBLIC är ofta publika DTDs som exempelvis XHMTLS DTD som kan nås via en unik URI som unikt identifierar den. Om man exempelvis anropar XHTML DTD:n genom att skriva anropet så vet parsern som i detta fall är browsern hur dokumentet ska se ut eftersom det är ofta är inbyggt.
exempelvis; XHTML DTD:
En PUBLIC DTD cachas alltså så den inte behöver laddas ner varje gång och återanvänds om man anropar den med rätt ID och URI.
Värt att komma ihåg är att den interna DTD:n har prioritet över den externa i de fall man använders sig av båda metoderna.
ELEMENT DEKLARATIONER
En valid DTD måste innehålla definitioner för alla taggar som ska användas i de designerade XML-dokumenten. Elementdeklarationerna är kastkänsliga och får inte innehålla specialtecken.
En elementdeklaration:
Efter elementdeklarationen måste man deklarera vilken typ av data elementet får innehålla.
De olika datatyperna är: ANY, EMPTY, #PCDATA, Elements, Mixed
Man måste även deklarera alla underelement till ett element: . Elementen måste komma i samma ordning i dokumentet som i DTD:n.
Vissa element kan ha olika underelement och då är det bra att definiera underelement med ”choice model” metoden: . Dock får ett ”choice model” element inte innehålla flera av de element som är i ”choice-läge”. Då får man istället skriva valen i en extra parantes: .
Eftersom vissa element kanske behöver vara med en eller flera gånger så måste man deklarera detta i DTD:n. Exempelvis kanske man behöver ett telefonnummer två gånger eller så kanske någon inte har ett emailkonto och därmed krävs inte detta i XML-filen. För att deklarera dessa variationer använder man ?,+ och * tecknet. ? kan t.ex. användas i fall som med emailen, där det inte är säkert informationen finns. + används när något måste finnas med minst en gång som ett telenummer. * betyder att ett element kan finnas i intervallet 0 till hur många som helst.
DEKLARERA DTD ATTRIBUT kap.3 XML 2nd ED.
Man måste även deklarera de attribut som elementen i XML-dokumenten kopplade till DTD:n får använda sig av.
För att åstadkomma detta måste man skapa en s.k. ”attribute-list declaration” i dokumentets DTD. Detta gör att man åstadkommer följande:
en lista med namn över alla attribut associerade med ett element
specifikation över varje attributs datatyp
indikation över om varje attribut är obligatoriskt eller valfritt
ett standardvärde för varje attribut om det är nödvändigt
Syntax:
Man kan även använda ATTLIST på varje rad istället, detta förenklar eftersom man kan kopiera raderna snabbare.
Attribute Tokens
”Tokenized types” är strängar som följer vissa regler för format och innehåll. DTD:er stödjer 4 typer av ”tokens”; ID, ID referenser, name tokens och entiteter.
En ID token används när ett attributvärde måste vara unikt inom ett dokument. Exempelvis custID för en unik kund i ett kundregister. Om detta attribut används som en ID token så kan varje custID attribut i dokumentet endast ha unika värden. Det innebär att samma kund ej kan lagras flera gånger på olika ställen eller att en annan kund av misstag får samma ID.
ID token: som kan se ut som:
Efter att man angett att ett visst element ska innehålla ID-tokens som attribut går det att referera till dessa objekt med IDREF-tokens. Givetvis måste ett sådant token ha samma värde som det ID det refererar till.
Exempel:
Nametokens är en datatyp som bara tillåter attributvärden med de tecken som är tillåtna inom XML. Därför skulle exempelvis inte blanksteg fungera i ett attribut med NMTOKEN som datatyp.
Attributvärden har även regler för hur de måste förekomma i dokumentet. Standardvärdet för ett attributvärde är #REQUIRED som innebär att det krävs ett attributvärde.
#IMPLIED innebär att förekomsten av ett attribut är valfritt.
”default” innebär att attributets förekomst är valfri men om inget attributvärde anges får det värdet default.
#FIXED default är som ”default” men om man anger ett värde så måste det matcha default-värdet.
exempel på #REQUIRED:
exempel på #IMPLIED:
exempel på #FIXED default:
Vidare kan man lagra entiteter som textsträngar och referera till dessa från XML-dokumentet. Detta gör man med: som kan se ut så här: .
Vill man referera till längre texter eller annan data så kan man lägga enitetsreferenser i en extern fil som sedan anropas med:. KOM IHÅG att denna XML fil som refereras (description.xml) inte får ha en XML-deklaration i början av dokumentet. Description.xml dokumentet ingår i moderdokumentet och därför gäller XML-deklarationen i denna.
Hur refererar man till referensentiteter inne i XML-dokumentet då?: &entity är svaret. Samma som när man vill använda specialtecken utan störa XML-parsern (& exempelvis för ”&”).
Därför blir det &DCT5Z för att anropa textsträngen ”Tapan Digital Camera 5 mpx – zoom”.
Så här ser det ut: &DCT5Z -> Tapan Digital Camera 5 mpx – zoom
Ofta när man jobbar med stora DTD dokument (ex: XHTML) så delar man upp DTD:n i moduler för att flera kodare med olika expertis kan ge sig på sina sektioner. Utan gå in på varför modularisering är awesome så kan vi ju definitivt se fördelarna i detta om man tänker i termer om felhantering.
Referens till extern parameterentitet:
Dock kan det nämnas att Firefox och Netscape-baserade webbläsare använder Expat för att parsa XML och denna parser stödjer inte nästlade DTD:s.
Konditionsbaserade DTD:er
Det går att skapa DTD:er som endast gäller om vissa krav uppfylls. Därför behöver man inte skapa olika DTD:er för olika ändamål, ibland kan man skriva in olika konditionsbaserade typer direkt i huvud DTD:n.
För att skapa en konditionell sektion till DTD:n: där keyword är antigen INCLUDE eller IGNORE. Deras betydelse är självklar.
EXEMPEL:
<!–
<!DOCTYPE customers
[
<!DOCTYPE customers
[
<!-- Product code descriptions inserted as general entities -->
<!ELEMENT customers (customer+)>
<!ELEMENT customer (name, address, phone, email?, orders)>
<!ATTLIST customer custID ID #REQUIRED>
<!ATTLIST customer custType (home | business) #IMPLIED>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name title (Mr. | Mrs. | Ms.) #IMPLIED>
<!ELEMENT address (#PCDATA)>
<!ELEMENT phone (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT orders (order+)>
<!ELEMENT order (orderDate, items)>
<!ATTLIST order orderID ID #REQUIRED>
<!ATTLIST order orderBy IDREF #REQUIRED>
<!ELEMENT orderDate (#PCDATA)>
<!ELEMENT items (item+)>
<!ELEMENT item (#PCDATA)>
<!ATTLIST item itemPrice CDATA #REQUIRED>
<!ATTLIST item itemQty CDATA "1">
<!ENTITY DCT5Z "Tapan Digital Camera 5 Mpx - zoom">
<!ENTITY SM128 "SmartMedia 128MB Card">
<!ENTITY RCL "Rechargeable Lithium Ion Battery">
<!ENTITY BCE4L "Battery Charger 4pt Lithium">
<!ENTITY WBC500 "WebNow Webcam 500">
<!ENTITY RCA "Rechargeable Alkaline Battery">
<!ENTITY SCL4C "Linton Flatbed Scanner 4c">
<!-- codes.dtd contains a list of product codes(IE only) -->
<!ENTITY % itemCodes SYSTEM "codes.dtd">
%itemCodes;
]>