Tutorial DTD
Tutorial DTD
Introduction to DTD
A Document Type Definition (DTD) defines the legal building blocks of an XML document. It defines the document structure with a list of legal elements and attributes. A DTD can be declared inline inside an XML document, or as an external reference.
<?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend</body> </note>
Open the XML file above in your browser (select "view source" or "view page source" to view the DTD) The DTD above is interpreted like this:
!DOCTYPE note defines that the root element of this document is note !ELEMENT note defines that the note element contains four elements: "to,from,heading,body" !ELEMENT to defines the to element to be of type "#PCDATA" !ELEMENT from defines the from element to be of type "#PCDATA" !ELEMENT heading defines the heading element to be of type "#PCDATA" !ELEMENT body defines the body element to be of type "#PCDATA"
<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
And this is the file "note.dtd" which contains the DTD:
Elements
Elements are the main building blocks of both XML and HTML documents. Examples of HTML elements are "body" and "table". Examples of XML elements could be "note" and "message". Elements can contain text, other elements, or be empty. Examples of empty HTML elements are "hr", "br" and "img". Examples:
Attributes
Attributes provide extra information about elements. Attributes are always placed inside the opening tag of an element. Attributes always come in name/value pairs. The following "img" element has additional information about a source file:
Entities
Some characters have a special meaning in XML, like the less than sign (<) that defines the start of an XML tag. Most of you know the HTML entity: " ". This "no-breaking-space" entity is used in HTML to insert an extra space in a document. Entities are expanded when a document is parsed by an XML parser. The following entities are predefined in XML:
PCDATA
PCDATA means parsed character data. Think of character data as the text found between the start tag and the end tag of an XML element. PCDATA is text that WILL be parsed by a parser. The text will be examined by the parser for entities and markup. Tags inside the text will be treated as markup and entities will be expanded. However, parsed character data should not contain any &, <, or > characters; these need to be represented by the & < and > entities, respectively.
CDATA
CDATA means character data. CDATA is text that will NOT be parsed by a parser. Tags inside the text will NOT be treated as markup and entities will not be expanded.
DTD - Elements
In a DTD, elements are declared with an ELEMENT declaration.
Declaring Elements
In a DTD, XML elements are declared with an element declaration with the following syntax:
Empty Elements
Empty elements are declared with the category keyword EMPTY:
<!ELEMENT element-name EMPTY> Example: <!ELEMENT br EMPTY> XML example: <br />
<!ELEMENT element-name (child1)> or <!ELEMENT element-name (child1,child2,...)> Example: <!ELEMENT note (to,from,heading,body)>
When children are declared in a sequence separated by commas, the children must appear in the same sequence in the document. In a full declaration, the children must also be declared, and the children can also have children. The full declaration of the "note" element is:
DTD - Attributes
In a DTD, attributes are declared with an ATTLIST declaration.
Declaring Attributes
An attribute declaration has the following syntax:
<!ATTLIST element-name attribute-name attribute-type default-value> DTD example: <!ATTLIST payment type CDATA "check"> XML example: <payment type="check" />
The attribute-type can be one of the following: Type CDATA (en1|en2|..) ID IDREF IDREFS NMTOKEN NMTOKENS ENTITY ENTITIES NOTATION xml: Description The value is character data The value must be one from an enumerated list The value is a unique id The value is the id of another element The value is a list of other ids The value is a valid XML name The value is a list of valid XML names The value is an entity The value is a list of entities The value is a name of a notation The value is a predefined xml value
The default-value can be one of the following: Value value #REQUIRED #IMPLIED #FIXED value Explanation The default value of the attribute The attribute is required The attribute is not required The attribute value is fixed
In the example above, the "square" element is defined to be an empty element with a "width" attribute of type CDATA. If no width is specified, it has a default value of 0.
#REQUIRED
Syntax
<!ATTLIST element-name attribute-name attribute-type #REQUIRED>
Example
DTD: <!ATTLIST person number CDATA #REQUIRED> Valid XML: <person number="5677" /> Invalid XML: <person />
Use the #REQUIRED keyword if you don't have an option for a default value, but still want to force the attribute to be present.
#IMPLIED
Syntax
<!ATTLIST element-name attribute-name attribute-type #IMPLIED>
Example
DTD: <!ATTLIST contact fax CDATA #IMPLIED> Valid XML: <contact fax="555-667788" /> Valid XML: <contact />
Use the #IMPLIED keyword if you don't want to force the author to include an attribute, and you don't have an option for a default value.
#FIXED
Syntax
<!ATTLIST element-name attribute-name attribute-type #FIXED "value">
Example
DTD: <!ATTLIST sender company CDATA #FIXED "Microsoft"> Valid XML: <sender company="Microsoft" /> Invalid XML: <sender company="W3Schools" />
Use the #FIXED keyword when you want an attribute to have a fixed value without allowing the author to change it. If an author includes another value, the XML parser will return an error.
Example
DTD: <!ATTLIST payment type (check|cash) "cash"> XML example: <payment type="check" /> or <payment type="cash" />
Use enumerated attribute values when you want the attribute value to be one of a fixed set of legal values.
<person sex="female"> <firstname>Anna</firstname> <lastname>Smith</lastname> </person> <person> <sex>female</sex> <firstname>Anna</firstname> <lastname>Smith</lastname> </person>
In the first example sex is an attribute. In the last, sex is a child element. Both examples provide the same information. There are no rules about when to use attributes, and when to use child elements. My experience is that attributes are handy in HTML, but in XML you should try to avoid them. Use child elements if the information feels like data.
My Favorite Way
I like to store data in child elements. The following three XML documents contain exactly the same information: A date attribute is used in the first example:
<note date="12/11/2002"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
A date element is used in the second example:
<note> <date>12/11/2002</date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
An expanded date element is used in the third: (THIS IS MY FAVORITE):
<note> <date> <day>12</day> <month>11</month> <year>2002</year> </date> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
attributes cannot contain multiple values (child elements can) attributes are not easily expandable (for future changes) attributes cannot describe structures (child elements can) attributes are more difficult to manipulate by program code attribute values are not easy to test against a DTD
If you use attributes as containers for data, you end up with documents that are difficult to read and maintain. Try to use elements to describe data. Use attributes only to provide information that is not relevant to the data. Don't end up like this (this is not how XML should be used):
<note day="12" month="11" year="2002" to="Tove" from="Jani" heading="Reminder" body="Don't forget me this weekend!"> </note>
<messages> <note id="p501"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> <note id="p502"> <to>Jani</to> <from>Tove</from> <heading>Re: Reminder</heading> <body>I will not!</body> </note>
</messages>
The ID in these examples is just a counter, or a unique identifier, to identify the different notes in the XML file, and not a part of the note data. What I am trying to say here is that metadata (data about data) should be stored as attributes, and that data itself should be stored as elements.
DTD - Entities
Previous Next Chapter
Entities are variables used to define shortcuts to standard text or special characters. Entity references are references to entities Entities can be declared internal or external
Example
DTD Example: <!ENTITY writer "Donald Duck."> <!ENTITY copyright "Copyright W3Schools."> XML example: <author>&writer;©right;</author>
Note: An entity has three parts: an ampersand (&), an entity name, and a semicolon (;).
Example
DTD Example: <!ENTITY writer SYSTEM "http://www.w3schools.com/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.w3schools.com/entities.dtd"> XML example: <author>&writer;©right;</author>
DTD Validation
With Internet Explorer 5+ you can validate your XML against a DTD.
Example
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.validateOnParse="true"; xmlDoc.load("note_dtd_error.xml"); document.write("<br />Error Code: "); document.write(xmlDoc.parseError.errorCode); document.write("<br />Error Reason: "); document.write(xmlDoc.parseError.reason); document.write("<br />Error Line: "); document.write(xmlDoc.parseError.line);
Try it yourself Look at the XML file
Example
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.validateOnParse="false"; xmlDoc.load("note_dtd_error.xml"); document.write("<br />Error Code: "); document.write(xmlDoc.parseError.errorCode); document.write("<br />Error Reason: "); document.write(xmlDoc.parseError.reason); document.write("<br />Error Line: "); document.write(xmlDoc.parseError.line);
Try it yourself
<!DOCTYPE TVSCHEDULE [ <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ATTLIST <!ATTLIST <!ATTLIST <!ATTLIST <!ATTLIST ]> TVSCHEDULE (CHANNEL+)> CHANNEL (BANNER,DAY+)> BANNER (#PCDATA)> DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)> HOLIDAY (#PCDATA)> DATE (#PCDATA)> PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)> TIME (#PCDATA)> TITLE (#PCDATA)> DESCRIPTION (#PCDATA)> TVSCHEDULE NAME CDATA #REQUIRED> CHANNEL CHAN CDATA #REQUIRED> PROGRAMSLOT VTR CDATA #IMPLIED> TITLE RATING CDATA #IMPLIED> TITLE LANGUAGE CDATA #IMPLIED>
<!DOCTYPE NEWSPAPER [ <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ATTLIST <!ATTLIST <!ATTLIST <!ATTLIST NEWSPAPER (ARTICLE+)> ARTICLE (HEADLINE,BYLINE,LEAD,BODY,NOTES)> HEADLINE (#PCDATA)> BYLINE (#PCDATA)> LEAD (#PCDATA)> BODY (#PCDATA)> NOTES (#PCDATA)> ARTICLE ARTICLE ARTICLE ARTICLE AUTHOR CDATA #REQUIRED> EDITOR CDATA #IMPLIED> DATE CDATA #IMPLIED> EDITION CDATA #IMPLIED>
<!ENTITY NEWSPAPER "Vervet Logic Times"> <!ENTITY PUBLISHER "Vervet Logic Press"> <!ENTITY COPYRIGHT "Copyright 1998 Vervet Logic Press"> ]>
<!ENTITY COMPANY "JD Power Tools, Inc."> <!ENTITY EMAIL "[email protected]"> <!ELEMENT CATALOG (PRODUCT+)> <!ELEMENT PRODUCT (SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)> <!ATTLIST PRODUCT NAME CDATA #IMPLIED CATEGORY (HandTool|Table|Shop-Professional) "HandTool" PARTNUM CDATA #IMPLIED PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago" INVENTORY (InStock|Backordered|Discontinued) "InStock"> <!ELEMENT SPECIFICATIONS (#PCDATA)> <!ATTLIST SPECIFICATIONS WEIGHT CDATA #IMPLIED POWER CDATA #IMPLIED> <!ELEMENT OPTIONS (#PCDATA)> <!ATTLIST OPTIONS FINISH (Metal|Polished|Matte) "Matte" ADAPTER (Included|Optional|NotApplicable) "Included" CASE (HardShell|Soft|NotApplicable) "HardShell"> <!ELEMENT PRICE (#PCDATA)> <!ATTLIST PRICE MSRP CDATA #IMPLIED WHOLESALE CDATA #IMPLIED STREET CDATA #IMPLIED SHIPPING CDATA #IMPLIED> <!ELEMENT NOTES (#PCDATA)> ]>