DTD tutorial: Difference between revisions

The educational technology and digital learning wiki
Jump to navigation Jump to search
 
 
(90 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<!-- <pageby nominor="false" comments="false"/> -->
{{web technology tutorial|intermediate}}
{{incomplete}}
== Introduction ==
== Introduction ==


This is a short tutorial about [[DTD]]s. It brievely shows how to read DTDs, then how to create these.
This is a short tutorial about creating simple [[DTD]]s ('''D'''ocument '''T'''ype '''D'''efinitions).


=== DTD grammars are a set of rules that define: ===
<div class="tut_goals">


* a set of '' elements'' (tags) and their '' attributes'' that can be used to create an XML document;
'''Learning goals'''
* '' how'' elements can be '' embedded'' ;
* different sorts of entities (reusable fragments, special characters).
* DTDs can't define what the contents look like, i.e. character data (element contents) and most attribute values.


=== Specification of a markup language ===
* Be able to read a DTD
* Be able to create a simple DTD with nested elements, i.e. understand combination features
* Be able to define attributes for elements
* Know how to create and use DTD entities


* The most important part is usually the DTD, but in addition other constraints can be added !
'''Prerequisites'''
* The DTD does not identify the root element !
** you have to tell the users what elements can be root elements
* Since DTDs can't express data constraints, write them out in a specification document
** e.g. "the value of length attribute is a string composed of a number plus "cm" or "inch" or "em"


  example: &lt;size length="10cm"&gt;
* [[XML]] (Conceptual overview)
* [[XML principles]] (important !)
* [[Tour de XML]] or équivalent (having seen some real world applications would be good for motivation)
* [[Editing XML tutorial]] (strongly recommended)


=== Example 1: A simple DTD ===
'''Next steps'''


* [[CSS for XML tutorial]] (Styling very text-centric contents)
* [[XML Schema tutorial - Basics]] (alternative schema language)
* [[XSLT Tutorial - Basics]] (Rendering XML contents by translating to HTML)
* [[XPath tutorial - basics]]
* [[XQuery tutorial - basics]] (if you have interest in XML databases)
* [[PHP - MySQL - XML tutorial - basics]] (shows how to display an XML result-set retrieved form MySQL with XSLT)


&lt;!ELEMENT page  (title, content, comment?)&gt;
</div>
&lt;!ELEMENT title (#PCDATA)&gt;
&lt;!ELEMENT content (#PCDATA)&gt;
&lt;!ELEMENT comment (#PCDATA)&gt;


* A DTD document contains just rules .... nothing else (see later for explanations)
=== Executive overview ===


'''DTD grammars are a set of rules that define:'''
# a set of ''elements'' (tags) and their ''attributes'' that can be used to create an [[XML]] document;
# ''how'' these elements can be ''combined/embedded'' ;
# different sorts of entities (reusable fragments, special characters).


== Using a DTD with an XML document ==
DTDs can't define element content types, i.e. what text can go inside elements. Most attribute can't be typed either. For example, with a DTD one cannot specify that input should be a number from 0 to 100..


=== A. Document type declarations ===
=== XML Principles recalled ===


* A '' valid'' XML document includes a '' declaration that specifies the DTD '' used
'''Specification of a markup language'''
* DTD is declared on top of the file after the XML declaration.
* XML declarations, DTD declaration etc. are part of the prologue
* So: The &lt;!DOCTYPE...&gt; declaration is part of the XML file, '' not'' the DTD ....


==== Example: ====
There are many ways of defining a XML language. You could write down the specification of an XML vocabulary in simple prose, or use a so-called Schema language, or finally, a combination of the two. The most simple schema language, i.e. DTDs, is defined in the XML Standard.


&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
'''DTD''' stands for '''Document Type Definition'''. A DTD is a set of rules that constitute a grammar (also called schema) that defines the so-called ''XML application'' also called ''XML vocabular''. For example, the file [http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd xhtml1-transitional.dtd] available at through the [http://www.w3.org/TR/xhtml1/dtds.html XHTML 1.0 specification] page, formally defines the grammar for the [[XHTML]] 1 web markup language.
&lt;!DOCTYPE ''hello'' SYSTEM "hello.dtd"&gt;
&lt;''hello''&gt;Here we &lt;strong&gt;go&lt;/strong&gt; ... &lt;''/hello''&gt;


==== 4 ways of using a DTD ====
* The most important part of a DTD-based markup language is usually the DTD itself, but in addition other constraints can be added in a design document.
* The DTD does not identify the root element ! You will have to tell the users what elements can be root elements.
* Since DTDs can't express data constraints, write them out in a specification document, e.g. "the value of ''length'' attribute is a string composed of a number plus "cm" or "inch" or "em". Examples:
<source lang="xml">
<size length="10cm">
<size length="3inch">
</source>


# No DTD (XML document will just be well-formed)
Example 1: A simple DTD
# DTD rules are defined inside the XML document
<source lang="xml">
#* We get a "standalone" document (the XML document is self-sufficient)
<!ELEMENT page  (title, content, comment?)>
# "Private/System" DTDs, the DTD is located on the system (own computer or the Internet)
<!ELEMENT title (#PCDATA)>
#* '' ... that's what you are going to use when you write your own DTDs''
<!ELEMENT content (#PCDATA)>
<!ELEMENT comment (#PCDATA)>
</source>


&lt;!DOCTYPE hello SYSTEM "hello.dtd"&gt;
A DTD document contains just rules and no XML declaration is needed ... more details later ...


# Public DTDs, we use a name for the DTD.
=== Associating a DTD with an XML document ===
#* means that both your XML editor and user software know the DTD
#* strategy used for common Web DTDs like XHTML, SVG, MathML, etc.


=== B. Syntax of the DTD declaration in the XML document ===
Before we learn how to create our own grammars, let's shortly recall how how to associate a DTD with an XML file. For more details, please read the [[Editing XML tutorial]].


* A DTD declaration starts with the keyword "DOCTYPE":
* In the XML file, you can add a '''declaration that specifies the DTD''' and that implicitly requires that XML contents must be validated.
 
* This DTD file is declared on top of the file after the XML declaration.
  &lt;!''DOCTYPE'' ....  &gt;
* XML declarations, DTD declaration etc. are part of the prologue
 
* ... followed by the root element
** Remember that DTDs don't know their root element, root is defined in the XML document !
** Note: DTDs must define this root element just like any other element ! (you can have more than one)
 
  &lt;!DOCTYPE ''hello'' .... &gt;


* ... followed by the DTD definition or a reference to a DTD file
; Example XML contents with a DTD declaration


==== Syntax for internal DTDs (only !) ====
<source lang="xml">
<?xml version="1.0" ?>
<!DOCTYPE hello SYSTEM "hello.dtd">


** DTD rules are inserted between brackets [ ... ]
<hello>Here we <strong>go</strong> ... </hello>


    &lt;!DOCTYPE hello ''[''
</source>
        ''&lt;!ELEMENT hello (#PCDATA)&gt;''
        '']&gt;''


==== Syntax to define "private" external DTDs: ====
Let us recall from the [[editing XML tutorial]], that there are four ways of using a DTD


** DTD is identified by the URL after the "'' SYSTEM'' " keyword
(1) '''No DTD'''  
* XML document will just be well-formed, or validation takes place in some other contexts, e.g. there exist tools that allow you to find out if a given XML document is valid with respect to a given DTD file)


&lt;!DOCTYPE hello '' SYSTEM "hello.dtd"'' &gt;
(2) '''DTD rules are defined inside the XML document'''
* We get a "standalone" document (the XML document is self-sufficient)


==== Syntax for public DTDs: ====
(3) '''"Private/System" DTDs'''
* As shown in the example above, the DTD is located on the system (own computer or the Internet). That's what you are going to use when you write your own DTDs.


* after the "'' PUBLIC'' " keyword you have to specify an official name and a backup URL that a validator could use.
(4) '''Public DTDs'''
* we use a name for the DTD. This means that both your XML editor and user software know the DTD. This is the strategy used for common Web DTDs like XHTML, SVG, MathML, etc.


&lt;!DOCTYPE rss ''PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"''
Finally, let us recall that other schema formalism than DTDs exist, e.g. [[XML Schema]].
'' "http://my.netscape.com/publish/formats/rss-0.91.dtd"''
&gt;


=== C. Some examples of XML documents with DTD declarations: ===
=== Sample XML documents with DTD declarations ===


=== Example 2: Hello XML without DTD ===
; Example 1 - Hello XML without DTD


  &lt;?xml version="1.0" ''standalone="yes"''
<source lang="xml">
?&gt;
  <?xml version="1.0" standalone="yes"?>
  &lt;hello&gt; Hello XML et hello cher lecteur ! &lt;/hello&gt;
  <hello> Hello XML et hello cher lecteur ! </hello>
</source>


=== Example 4-3: Hello XML with an internal DTD ===
;Example 2 - Hello XML with an internal DTD


&lt;?xml version="1.0" ''standalone="yes"''
<source lang="xml">
?&gt;
  <?xml version="1.0" standalone="yes"?>
''&lt;!DOCTYPE hello [''
  <!DOCTYPE hello [
''  &lt;!ELEMENT hello (#PCDATA)&gt;''
    <!ELEMENT hello (#PCDATA)>
''  ]&gt;''
    ]>
&lt;hello&gt; Hello XML et hello ch�re lectrice ! &lt;/hello&gt;


=== Example 4: Hello XML with an external DTD ===
  <hello> Hello XML et hello dear readers ! </hello>
</source>


&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
;Example 3 - Hello XML with an external DTD
''&lt;!DOCTYPE hello SYSTEM "hello.dtd"&gt;''
: That's what you should with your own home-made DTDs
&lt;hello&gt; This is a very simple XML document &lt;/hello&gt;


* That's what you should with your own home-made DTDs
<source lang="xml">
<?xml version="1.0" ?>
<!DOCTYPE hello SYSTEM "hello.dtd">
<hello> This is a very simple XML document </hello>
</source>


=== Example 4-5: XML with a public external DTD (RSS 0.91) ===
;Example 4 - XML with a public external DTD (RSS 0.91)


  &lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
<source lang="xml">
  ''&lt;!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"''
  <?xml version="1.0" ?>
'' "http://my.netscape.com/publish/formats/rss-0.91.dtd"&gt;''
  <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
  &lt;rss version="0.91"&gt;
  "http://my.netscape.com/publish/formats/rss-0.91.dtd">
  &lt;channel&gt; ...... &lt;/channel&gt;
  <rss version="0.91">
  &lt;/rss&gt;
  <channel> ...... </channel>
  </rss>
</source>


== 4.2 Understanding DTDs by example ==
== Understanding DTDs by example ==


* Recall that DTDs define all the elements and attributes and the way they can be combined
Recall that DTDs define all the elements and attributes and the way they can be combined


=== Example 6: Hello text with XML ===
=== Example 6: Hello text with XML ===


==== A simple XML document of type '' &lt;page&gt;'' ====
;A simple XML document of type <nowiki><page></nowiki>


  ''&lt;page&gt;''
<source lang="xml">
   &lt;title&gt;Hello friend&lt;/title&gt;
<?xml version="1.0"?>
   &lt;content&gt;Here is some content :)&lt;/content&gt;
  <page>
   &lt;comment&gt;Written by DKS/Tecfa, adapted from S.M./the Cocoon samples&lt;/comment&gt;
   <title>Hello friend</title>
  ''&lt;/page&gt;''
   <content>Here is some content :)</content>
   <comment>Written by DKS/Tecfa, adapted from S.M./the Cocoon samples</comment>
  </page>
</source>


==== A DTD that would validate the document ====
;A DTD that would validate this "page" document


[[Image:xml-intro-edit-6.png]]
[[Image:xml-intro-edit-6.png]]


=== Example 4-7: A recipe list in XML ===
=== Example 7: A recipe list in XML ===


* init/simple_recipe.xml
* Source: Introduction to XML by Jay Greenspan (now dead URL)
* Source: Introduction to XML by Jay Greenspan (now dead URL)


   &lt;?xml version="1.0"?&gt;
<source lang="xml">
   ''&lt;!DOCTYPE list SYSTEM "simple_recipe.dtd"&gt;''
   <?xml version="1.0"?>
   &lt;list&gt;
   <!DOCTYPE list SYSTEM "simple_recipe.dtd">
   &lt;recipe&gt;
   <list>
     &lt;author&gt;Carol Schmidt&lt;/author&gt;
   <recipe>
     &lt;recipe_name&gt;Chocolate Chip Bars&lt;/recipe_name&gt;
     <author>Carol Schmidt</author>
     &lt;meal&gt;Dinner&lt;/meal&gt;
     <recipe_name>Chocolate Chip Bars</recipe_name>
     &lt;ingredients&gt;
     <meal>Dinner</meal>
       &lt;item&gt;2/3 C butter&lt;/item&gt;     &lt;item&gt;2 C brown sugar&lt;/item&gt;
     <ingredients>
       &lt;item&gt;1 tsp vanilla&lt;/item&gt;     &lt;item&gt;1 3/4 C unsifted all-purpose flour&lt;/item&gt;
       <item>2/3 C butter</item>     <item>2 C brown sugar</item>
       &lt;item&gt;1 1/2 tsp baking powder&lt;/item&gt;
       <item>1 tsp vanilla</item>     <item>1 3/4 C unsifted all-purpose flour</item>
       &lt;item&gt;1/2 tsp salt&lt;/item&gt;     &lt;item&gt;3 eggs&lt;/item&gt;
       <item>1 1/2 tsp baking powder</item>
       &lt;item&gt;1/2 C chopped nuts&lt;/item&gt;
       <item>1/2 tsp salt</item>     <item>3 eggs</item>
       &lt;item&gt;2 cups (12-oz pkg.) semi-sweet choc. chips&lt;/item&gt;
       <item>1/2 C chopped nuts</item>
     &lt;/ingredients&gt;
       <item>2 cups (12-oz pkg.) semi-sweet choc. chips</item>
     &lt;directions&gt;
     </ingredients>
  Preheat oven to 350 degrees. Melt butter; combine with brown sugar and vanilla in large mixing bowl. Set aside to cool. Combine flour, baking powder, and salt; set aside. Add eggs to cooled sugar mixture; beat well. Stir in reserved dry ingredients, nuts, and chips.
     <directions>
  Spread in greased 13-by-9-inch pan. Bake for 25 to 30 minutes until golden brown; cool.  Cut into squares.
  Preheat oven to 350 degrees.  
     &lt;/directions&gt;
Melt butter; combine with brown sugar and vanilla in large mixing bowl.  
   &lt;/recipe&gt;
Set aside to cool. Combine flour, baking powder, and salt; set aside.  
  &lt;/list&gt;
Add eggs to cooled sugar mixture; beat well.  
<div>
Stir in reserved dry ingredients, nuts, and chips.  
  Spread in greased 13-by-9-inch pan.
Bake for 25 to 30 minutes until golden brown; cool.  Cut into squares.
     </directions>
   </recipe>
  </list>
</source>


==== Contents of the DTD ====
;Contents of the DTD


[[Image:xml-intro-edit-7.png]]
[[Image:xml-intro-edit-7.png]]


=== Example 4-8: A simple story grammar ===
=== Example 8: A simple story grammar ===
 
<source lang="xml">
<?xml version="1.0" "?>
<!-- DTD to write simple stories
      Made by Daniel K. Schneider / TECFA / University of Geneva
      VERSION 1.0
      30/10/2003 -->
<!ELEMENT STORY (title, context, problem, goal, THREADS, moral, INFOS)>
<!ATTLIST STORY xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
<!ELEMENT THREADS (EPISODE+)>
<!ELEMENT EPISODE (subgoal, ATTEMPT+, result) >
<!ELEMENT ATTEMPT (action | EPISODE) >
<!ELEMENT INFOS ( ( date | author | a )* ) >
<!ELEMENT title (#PCDATA) >
<!ELEMENT context (#PCDATA) >
<!ELEMENT problem (#PCDATA) >
<!ELEMENT goal (#PCDATA) >
<!ELEMENT subgoal (#PCDATA) >
<!ELEMENT result (#PCDATA) >
<!ELEMENT moral (#PCDATA) >
<!ELEMENT action (#PCDATA) >
<!ELEMENT date (#PCDATA) >
<!ELEMENT author (#PCDATA) >
<!ELEMENT a (#PCDATA)>
<!ATTLIST a
      xlink:href CDATA #REQUIRED
      xlink:type CDATA #FIXED "simple">
</source>
;Here is a valid skeleton
<source lang="xml">
  <?xml version="1.0" " ?>
  <!DOCTYPE STORY SYSTEM "story-grammar.dtd">
  <?xml-stylesheet href="story-grammar.css" type="text/css"?>
  <STORY>
  <title>The little XMLer</title>
  <context></context>
  <problem></problem>
  <goal></goal>
  <THREADS>
    <EPISODE>
      <subgoal>I have to do it ...</subgoal>
      <ATTEMPT>
        <action></action>
      </ATTEMPT>
      <result></result>
    </EPISODE>
  </THREADS>
  <moral></moral>
  <INFOS>
  </INFOS>
</STORY>
</source>
 
The picture gives some extra information


[[Image:xml-intro-edit-8.png]]
[[Image:xml-intro-edit-8.png]]


=== Example 4-9: Lone family DTD ===
=== Example 9: Lone family DTD ===


[[Image:xml-intro-edit-9.png]]
[[Image:xml-intro-edit-9.png]]


==== A valid XML file ====
;A valid XML file


  &lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
<source lang="xml">
  &lt;!DOCTYPE family SYSTEM "family.dtd"&gt;
  <?xml version="1.0" ?>
  &lt;family&gt;
  <!DOCTYPE family SYSTEM "family.dtd">
   &lt;person name="Joe Miller" gender="male"
  <family>
           type="father" id="123.456.789"/&gt;
   <person name="Joe Miller" gender="male"
   &lt;person name="Josette Miller" gender="female"
           type="father" id="123.456.789"/>
           type="girl" id="123.456.987"/&gt;
   <person name="Josette Miller" gender="female"
  &lt;/family&gt;
           type="girl" id="123.456.987"/>
  </family>
</source>


=== Example 4-10: RSS ===
=== Example 10: RSS ===


* complex/rss-0-92.dtd
* There are several RSS standards. RSS 0.91 is Netscape's original (still being used)
* There are several RSS standards. RSS 0.91 is Netscape's original (still being used)


  &lt;!ELEMENT rss (channel)&gt;
<source lang="xml">
  &lt;!ATTLIST rss version CDATA #REQUIRED&gt; &lt;!-- must be "0.91"&gt; --&gt;
  <!ELEMENT rss (channel)>
&lt;!ELEMENT channel (title | description | link | language | item  | rating? | image? | textinput? | copyright? | pubDate? | lastBuildDate? | docs? | managingEditor? | webMaster? | skipHours? | skipDays?)*&gt;
  <!ATTLIST rss version CDATA #REQUIRED>
  <!-- must be "0.91"> -->
  <!ELEMENT channel (title | description | link | language | item  | rating? | image? | textinput? |  
              copyright? | pubDate? | lastBuildDate? | docs? | managingEditor? |  
              webMaster? | skipHours? | skipDays?)*>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT description (#PCDATA)>
  <!ELEMENT link (#PCDATA)>
  <!ELEMENT image (title | url | link | width? | height? | description?)*>
  <!ELEMENT url (#PCDATA)>
  <!ELEMENT item (title | link | description)*>
  <!ELEMENT textinput (title | description | name | link)*>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT rating (#PCDATA)>
  <!ELEMENT language (#PCDATA)>
  <!ELEMENT width (#PCDATA)>
  <!ELEMENT height (#PCDATA)>
  <!ELEMENT copyright (#PCDATA)>
  <!ELEMENT pubDate (#PCDATA)>
  <!ELEMENT lastBuildDate (#PCDATA)>
  <!ELEMENT docs (#PCDATA)>
  <!ELEMENT managingEditor (#PCDATA)>
  <!ELEMENT webMaster (#PCDATA)>
  <!ELEMENT hour (#PCDATA)>
  <!ELEMENT day (#PCDATA)>
  <!ELEMENT skipHours (hour )>
  <!ELEMENT skipDays (day )>
</source>
 
; Possible XML document for RSS
 
<source lang="xml">
  <?xml version="1.0" " ?>
  <!DOCTYPE rss SYSTEM "rss-0.91.dtd">
  <rss version="0.91">
    <channel>
      <title>Webster University</title>
      <description>Home Page of Webster University</description>
      <link>http://www.webster.edu</link>
      <item>
<title>Webster Univ. Geneva</title>
<description>Home page of Webster University Geneva</description>
<link>http://www.webster.ch</link>
      </item>
      <item>
<title>http://www.course.com/</title>
<description>You can find Thomson text-books materials (exercise data) on this web site</description>
<link>http://www.course.com/</link>
      </item>
    </channel>
  </rss>
</source>
 
== Definition of elements ==
 
Le us recall what DTD grammars are supposed to do. DTDs define
# a set of '' elements'' (tags) and their '' attributes'' that can be used to create an XML document;
# and define ''how'' elements can be ''embedded'';
 
In addition, a DTD may define different sorts of entities (reusable fragments) and attribute types for elements. We shall explain the use of attributes and entities below.
 
'''Syntax of a DTD rule to define elements:
 
  <!ELEMENT tag_name (child_element_specification) >
 
''child_element_specification'' may contain:
 
* A combination of child elements according to combination rules that we will introduce below.
 
<source lang="xml">
<!ELEMENT page  (title, content, comment?)>
</source>
 
* Mixed contents, i.e. child elements mixed with data (#PCDATA)
:'''important''': The #PCDATA element must come first !
<source lang="xml">
<!ELEMENT para (#PCDATA | strong)*>
</source>
* <nowiki>#PCDATA (Just data)</nowiki>
 
<source lang="xml">
<!ELEMENT title (#PCDATA)>
</source>
 
* ANY (only used during development)


  &lt;!ELEMENT title (#PCDATA)&gt;  &lt;!ELEMENT description (#PCDATA)&gt;  &lt;!ELEMENT link (#PCDATA)&gt;  &lt;!ELEMENT image (title | url | link | width? | height? | description?)*&gt;  &lt;!ELEMENT url (#PCDATA)&gt;  &lt;!ELEMENT item (title | link | description)*&gt;  &lt;!ELEMENT textinput (title | description | name | link)*&gt;  &lt;!ELEMENT name (#PCDATA)&gt;  &lt;!ELEMENT rating (#PCDATA)&gt;  &lt;!ELEMENT language (#PCDATA)&gt;  &lt;!ELEMENT width (#PCDATA)&gt;  &lt;!ELEMENT height (#PCDATA)&gt;  &lt;!ELEMENT copyright (#PCDATA)&gt;  &lt;!ELEMENT pubDate (#PCDATA)&gt;  &lt;!ELEMENT lastBuildDate (#PCDATA)&gt;  &lt;!ELEMENT docs (#PCDATA)&gt;  &lt;!ELEMENT managingEditor (#PCDATA)&gt;  &lt;!ELEMENT webMaster (#PCDATA)&gt;  &lt;!ELEMENT hour (#PCDATA)&gt;  &lt;!ELEMENT day (#PCDATA)&gt;  &lt;!ELEMENT skipHours (hour )&gt;  &lt;!ELEMENT skipDays (day )&gt;
<source lang="xml">
  <!ELEMENT para (ANY)*>
</source>


==== Possible XML document for RSS ====
* EMPTY (the element has no contents)


&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
<source lang="xml">
  &lt;!DOCTYPE rss SYSTEM "rss-0.91.dtd"&gt;
  <!ELEMENT person EMPTY>
&lt;rss version="0.91"&gt;    &lt;channel&gt;      &lt;title&gt;Webster University&lt;/title&gt;      &lt;description&gt;Home Page of Webster University&lt;/description&gt;      &lt;link&gt;http://www.webster.edu&lt;/link&gt;      &lt;item&gt;        &lt;title&gt;Webster Univ. Geneva&lt;/title&gt;        &lt;description&gt;Home page of Webster University Geneva&lt;/description&gt;        &lt;link&gt;http://www.webster.ch&lt;/link&gt;      &lt;/item&gt;      &lt;item&gt;        &lt;title&gt;http://www.course.com/&lt;/title&gt;        &lt;description&gt;You can find Thomson text-books materials (exercise data) on this web site&lt;/description&gt;        &lt;link&gt;http://www.course.com/&lt;/link&gt;      &lt;/item&gt;    &lt;/channel&gt;  &lt;/rss&gt;
</source>


== Summary syntax of element definitions ==
=== Tag names ===


* The purpose of this table is not to teach you how to write DTDs
Each tag name must start with a letter or an underscore ('_')<br /> followed by letters, numbers or the following characters: '_' , '-', '.', ':'
* To understand how to use DTDs, you just need to know how to read a DTD
 
{| border="1"
'''Bad''' examples
! rowspan="1" colspan="1" |
  <!ELEMENT 1st ...>
syntax element
  <!ELEMENT My Home ...>
! rowspan="1" colspan="1" |
 
short explanation
'''Good''' examples:
! rowspan="1" colspan="1" |
  <!ELEMENT First ...>
Example Element definitions  Valid XML example
  <!ELEMENT My_Home ...>
 
=== Combination rules ===
 
By using the combination rules an information architect (you!) defines how elements can be combined, i.e. mandatory and optional child elements, order of elements, and repetition.
 
Each and every element in your language must be defined with an <nowiki><!ELEMENT ></nowiki> rule
 
 
{| class="wikitable"
! A&nbsp;and&nbsp;B = tags
! Explanation
! DTD examples
! XML examples
|-
|-
| rowspan="1" colspan="1" |
| A , B
,
| A followed by B
| rowspan="1" colspan="1" |
 
** elements in that order
Elements in that order
| rowspan="1" colspan="1" |
| <source lang="xml">
&lt;!ELEMENT Name (First, Middle, Last)&gt;
<!ELEMENT person
** Element Name must contain First, Middle and Last
          ( name ,email? )>
  &lt;Name&gt;
</source>
  &lt;First&gt;D.&lt;/First&gt;&lt;Middle&gt;K.&lt;/Middle&gt;&lt;Last&gt;S.&lt;/Last&gt;
<source lang="xml">
&lt;/Name&gt;
<!ELEMENT Name
          (First, Middle, Last)>
</source>
|<source lang="xml">
<person>
<name>Joe</name>
  <email>x@x.x</email>
</person>
</source>
 
<source lang="xml">
<Name>
<First>D.</First>
<Middle>K.</Middle>
<Last>S.</Last>
</Name>
</source>
|-
|-
| rowspan="1" colspan="1" |
| A?
?
| A is optional,
| rowspan="1" colspan="1" |
 
** optional element
(it can be present or absent)
| rowspan="1" colspan="1" |
|<source lang="xml">
&lt;!ELEMENT Name (First,Middle?,Last)&gt;
<!ELEMENT person
====== Middle is optional ======
          (name,  email? )>
  &lt;Name&gt;&lt;First&gt;D.&lt;/First&gt;&lt;Last&gt;S.&lt;/Last&gt;&lt;/Name&gt;
</source>
<source lang="xml">
<!ELEMENT Name
          (First,Middle?,Last)>
</source>
| <source lang="xml">
<person>
  <name>Joe</name>
</person>
</source>
<source lang="xml">
<Name>
  <First>D.</First>
<Last>S.</Last>
</Name>
</source>
|-
|-
| rowspan="1" colspan="1" |
| A+
| rowspan="1" colspan="1" |
| At least one A
** at least one element
|<source lang="xml">
| rowspan="1" colspan="1" |
<!ELEMENT person
&lt;!ELEMENT list (movie )
          (name,  email+ )>
  &lt;list&gt;&lt;movie&gt;Return of ...&lt;/movie&gt;
</source>
      &lt;movie&gt;Comeback of ...&lt;/movie&gt; &lt;/list&gt;
<source lang="xml">
<!ELEMENT list  
          (movie+)
</source>
| <source lang="xml">
<person> <name>Joe</name>
  <email>x@x.x</email></person>
<person> <name>Joe</name>
  <email>x@x.x</email>
  <email>x@y.x</email>
</person></source>
<source lang="xml">
  <list>
    <movie>Return of ...</movie>
    <movie>Comeback of ...</movie>
</list></source>
|-
|-
| rowspan="1" colspan="1" |
| A*
<nowiki>*</nowiki>
| Zero, one or several A
| rowspan="1" colspan="1" |
| <source lang="xml">
** zero or more elements
  <!ELEMENT person
| rowspan="1" colspan="1" |
          (name,  email* )>
&lt;!ELEMENT list (item*)
</source>
====== almost as above, but list can be empty ======
<source lang="xml">
  <!ELEMENT list
            (item*)
</source>
| <source lang="xml">
<person>
  <name>Joe</name>
</person>
</source>
<source lang="xml">
  <list>
  <item>Return of ...</item>
  </list></source>
|-
|-
| rowspan="1" colspan="1" |
| A <nowiki>|</nowiki> B
<nowiki>|</nowiki>
| Either A or B
| rowspan="1" colspan="1" |
|<source lang="xml">
** pick one (or operator)
<!ELEMENT person
| rowspan="1" colspan="1" |
          ( email | fax )>
&lt;!ELEMENT major (economics | law)
</source>
&lt;major&gt; &lt;economics&gt; &lt;/economics&gt; &lt;/major&gt;
<source lang="xml">
<!ELEMENT major  
          (economics | law)>
</source>
| <source lang="xml">
<person> <name>Joe</name>
  <email>x@x.x</email>
</person>
 
<person> <name>Joe</name>
  <fax>123456789</fax>
</person></source>
<source lang="xml">
<major>
  <economics> </economics>
/major>
</source>
|-
|-
| rowspan="1" colspan="1" |
| (A, B)
()
| Parenthesis will group and you can
| rowspan="1" colspan="1" |
apply the above combination rules to the whole group
** grouping construct, e.g. one can add ? or * or to a group.
| <source lang="xml">
| rowspan="1" colspan="1" |
  <!ELEMENT text  
&lt;!ELEMENT text (para | list | title)*
            (para | list | title)*>
&lt;text&gt;
</source>
  &lt;title&gt;Story&lt;/title&gt;&lt;para&gt;Once upon a time&lt;/para&gt; &lt;title&gt;The awakening&lt;/title&gt; &lt;list&gt; ... &lt;/list&gt;
|<source lang="xml">
&lt;/text&gt;
<text>
  <title>Story</title>
<para>Once upon a time</para>
<title>The awakening</title>
<list> ... </list>
</text>
</source>
|}
|}


== Defining elements ==
=== Contents of DTD elements ===


As explained above, DTDs allow to define four different kinds of XML elements with respect to their content. XML elements can either include just other elements, just data (no elements), so-called mixed contents, or no data. We illustrate this with examples:


== 5.1 Definition of elements ==
'''(1) Child elements only'''
<source lang="xml">
<ul>
<li>Item 1</li>
<li>Item 2</li><li>Item 3</li>
</ul>
</source>


==== Rough syntax of a DTD rule to define elements: ====
'''(2) Data only'''
<source lang="xml">
<para>Here we go</para></source>


&lt;!ELEMENT tag_name child_element_specification&gt;
'''(3) Mixed contents, i.e. both data and elements
<source lang="xml">
<para>Here we go <bold>fast</bold></para></source>


==== Child_element_specification may contain: ====
'''(4) Empty elements'''
<source lang="xml">
<newline/>
</source>


* A combination of child elements according to combination rules
The following table summarizes how DTDs allow to define element contents other than combinations of child elements.


  &lt;!ELEMENT page (title, content, comment?)&gt;
{| class="wikitable"  
! Special elements
! Explanation
! DTD examples
! XML example
|-
|  #PCDATA
| "Parsed Character Data"
 
Text contents of an element. It should not contain any &lt;,&gt;,&amp; etc.
|  <!ELEMENT email (#PCDATA)>
| <source lang="xml">
<email>Daniel.Schneider@nowhere.org</email></source>
|-
| ANY
| Allows any non-specified child elements and parsed character data
(avoid this !!!)
|  <!ELEMENT person ANY>
| <source lang="xml">
<person>
  <c>text</c>
  <a>some <b>bbb</b>inside</a>
</person></source>
|-
|  EMPTY
|  No contents
|  <!ELEMENT br EMTPY>
|  <nowiki><br/></nowiki>
|}


* Mixed contents, i.e. child elements plus #PCDATA or ANY
'''Mixed element contents''' contain both text and tags (elements)


  &lt;!ELEMENT para (strong | #PCDATA )*&gt;
Example:
<source lang="xml">
  <para> here is a <a href="xx">link</a>. <b>Check</b> it out </para></source>


* <nowiki>#PCDATA (Just data)</nowiki>
To allow for these mixed contents, one '''must''' , as shown in the good examples below.
* use the "|" construct for listing the alternatives
*  Make it repeatable using the (....)* construct.
*  specify #PCDATA first
 
;Good examples:


  &lt;!ELEMENT title (#PCDATA)&gt;
<source lang="xml">
  <!ELEMENT para (#PCDATA|a|ul|b|i|em)* > 
<!ELEMENT p (#PCDATA | a | abbr | acronym | br | cite | code | dfn | em | img | kbd |
          q | samp | span | strong | var )* > 
<!ELEMENT par (#PCDATA | %font; | %phrase; | %special; | %form;)* >
</source>


* ANY (only used during development)
;Bad examples:


  &lt;!ELEMENT para (ANY)*&gt;
<source lang="xml">
  <!ELEMENT p (name, first_name, #PCDATA)*>
<!ELEMENT p (name | first_name | #PCDATA)*>  <!-- #PCDATA is not first -->
<!ELEMENT p ( (#PCDATA) |a|ul|b|i|em)*>
</source>


* EMPTY (the element has no contents)
== Defining attributes ==


&lt;!ELEMENT person EMPTY&gt;
Usually an object is defined in terms of its properties and its contents. Translated to XML, objects are usually represented as elements and its properties as attributes. However properties also could be expressed with child elements and the other way round...


==== Tag names ====
=== Rough syntax of Attribute rules: ===


* Each tag name must start with a letter or an underscore ('_')<br /> followed by letters, numbers or the following characters: '_' , '-', '.', ':'
<!ATTLIST element_name attr_name Attribute_type Type_Definition Default >


  ''BAD example:''
Here are some XML elements with attributes
  &lt;!ELEMENT 1st ...&gt;
  <img src="picture.png"/>
<person name="Joe Miller" gender="male" type="father" id="N123456789"/>
<a href="http://no.com/bla">no company</a>


  ''BAD example:''
When we define such attributes we always start with the same pattern:
   
<source lang="xml">
  &lt;!ELEMENT My Home ...&gt;
  <!ATTLIST name_of_element name_of_attribute ... >
</source>
for example
<source lang="xml">
  <!ATTLIST person name ...>
</source>


== 5.2 Combination rules ==
We then must provide an '''attribute type''' using a keyword. There exist six attribute types: '''normal text''', '''single word''', an ''ID'', a (or more) '''reference(s) to an ID''' of another attribute, and a '''list of values'''. These types are summarized in the following table.


{| border="1"
{| class="wikitable"
! rowspan="1" colspan="1" |
! Keyword
A and B = tags
! Attribute types
! rowspan="1" colspan="1" |
Explanation
! rowspan="1" colspan="1" |
DTD example
! rowspan="1" colspan="1" |
XML example
|-
|-
| rowspan="1" colspan="1" |
| CDATA
A , B
| "Character Data" - Text data
| rowspan="1" colspan="1" |
|-
A followed by B
| NMTOKEN
| rowspan="1" colspan="1" |
| A single word (no spaces or punctuations)
&lt;!ELEMENT person
|-
| ID
| Unique identifier of the element.
|-
| IDREF
| Reference to an identifier.
|-
| IDREFS
| Reference to one or more identifiers
|-
| <nowiki>(A|B|C|..)</nowiki>
| List of values (from which the user must choose)
|}


('' name ,email?'' )&gt;
Finally, we have to decide whether an attribute is mandatory, optional or fixed.
| rowspan="1" colspan="1" |
&lt;person&gt;


&lt;name&gt;Joe&lt;/name&gt;
{| class="wikitable" 
! Keyword
! Type Definition
|-
| <nowiki>#IMPLIED</nowiki>
| Attribute is optional
|-
| <nowiki>#REQUIRED</nowiki>
| Attribute is mandatory
|-
| <nowiki>#FIXED Value</nowiki>
| Attribute has a fixed value (user can't change it)
|}


&lt;email&gt;x@x.x&lt;/email&gt;
Below are some illustrations of valid attribute definitions


&lt;/person&gt;
{| class="wikitable" 
! DTD rule
! example XML
|-
| <source lang="XML"><!ATTLIST person first_name CDATA #REQUIRED></source>
| <person first_name="Joe">
|-
| <source lang="XML"><!ATTLIST person gender (male|female) #IMPLIED></source>
| <person gender="male">
|-
| <source lang="XML"><!ATTLIST form method CDATA #FIXED "POST"></source>
| <form method="POST">
|-
| <source lang="XML"><!ATTLIST list type (bullets|ordered) "ordered"></source>
| <list type="bullets">
|-
| <source lang="XML"><!ATTLIST sibling type (brother|sister) #REQUIRED></source>
| <sibling type="brother">
|-
|-
| rowspan="1" colspan="1" |
| <source lang="XML"><!ATTLIST person id ID #REQUIRED></source>
A?
| <person id="N1004">
| rowspan="1" colspan="1" |
|}
A is optional,


(it can be present or absent)
=== Shortcut to define multiple attributes for an element: ===
| rowspan="1" colspan="1" |
 
&lt;!ELEMENT person
Instead of defining each attribute with a different instruction, you can define all attributes for an element with a single one.
<source lang="xml">
<!ATTLIST target_tag
          attr1_nom TypeAttribut TypeDef Defaut
          attr2_nom TypeAttribut TypeDef Defaut
...>
</source>
 
; Example
 
<source lang="xml">
<!ATTLIST person ident ID #REQUIRED
      gender (male|female) #IMPLIED
      nom CDATA #REQUIRED
      prenom CDATA #REQUIRED 
      relation  brother|sister) #REQUIRED > 
<!ATTLIST portable owner IDREF #REQUIRED >
</source>


(name, '' email?'' )&gt;
=== Example: Lone family DTD (file family.dtd) ===
| rowspan="1" colspan="1" |
&lt;person&gt;


&lt;name&gt;Joe&lt;/name&gt;&lt;/person&gt;
[[Image:xml-intro-edit-10.png]]
|-
| rowspan="1" colspan="1" |
A
| rowspan="1" colspan="1" |
At least one A
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


(name, '' email '' )&gt;
; A valid family XML file
| rowspan="1" colspan="1" |
&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
<source lang="xml">
<?xml version="1.0" ?>
<!DOCTYPE family SYSTEM "family.dtd">
<family>
  <person name="Joe Miller" gender="male"
          type="father" id="N123456789"/>
  <person name="Josette Miller" gender="female"
          type="girl" id="N123456987"/>
</family>
</source>


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
=== ID, IDREF and IDREFS ===
Attributes of type ID, IDREF and IDREFS are checked for validity. That means:
* Each ID value must be unique and start with a letter
* Each IDREF value IDREFS list of values must point to an element with an existing ID value.


&lt;email&gt;x@x.x&lt;/email&gt;
Below is an XML (standalone) example that demonstrates use of an ID an IDREF, and an IDREFS attribute in order to create links between persons.
<source lang="XML">
<?xml version = "1.0"?>
<!DOCTYPE Folks [
<!ELEMENT Folks (Person*)>
<!ELEMENT Person (Name,Email?)>
<!ATTLIST Person Pin ID #REQUIRED>
<!ATTLIST Person Friend IDREF #IMPLIED>
<!ATTLIST Person Likes IDREFS #IMPLIED>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Email (#PCDATA)>
]>
<Folks>
    <Person Pin = "N1">
      <Name>Someone</Name>
    </Person>


&lt;email&gt;x@y.x&lt;/email&gt;
    <Person Pin = "N2" Friend = "N1">
      <Name>Someone else</Name>
    </Person>
   
    <Person Pin = "N3" Likes = "N2 N1">
      <Name>Fan</Name>
    </Person>
</Folks>
</source>


&lt;/person&gt;
Tip: If you want to avoid strong constraints when you create linking elements, just use normal attribute types ....
|-
| rowspan="1" colspan="1" |
A*
| rowspan="1" colspan="1" |
Zero, one or several A
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


(name, '' email*'' )&gt;
== Entities ==
| rowspan="1" colspan="1" |
&lt;person&gt;


&lt;name&gt;Joe&lt;/name&gt;
Entities can be defined as reusable fragments that are either substituted in the DTD or the XML.


&lt;/person&gt;
=== General entities ===
|-
| rowspan="1" colspan="1" |
A | B
| rowspan="1" colspan="1" |
Either A or B
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


('' email | fax'' )&gt;
Consider entities as abbreviations for some other content. An entity must be defined in the DTD and its contents are substituted when encountered in the XML file. Then, recall that XML initially only defines 5 entities and that HTML does many more...
| rowspan="1" colspan="1" |
&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
* Use the '' &amp;lt; &amp;amp; &amp;gt; &amp;aquot; &amp;apos;'' entities to refer to  &lt;, &amp;, &gt; ,",  and '


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
Syntax of an internal entity definition: 
: <!ENTITY entity_name "content">


&lt;fax&gt;123456789&lt;/fax&gt;&lt;/person&gt;
Syntax of an external entity definition, i.e. contents are defined in a file:
|-
: <!ENTITY entity_name SYSTEM "URI">
| rowspan="1" colspan="1" |
(A, B)
| rowspan="1" colspan="1" |
Parenthesis will group and you can apply the above combination rules to the whole group
| rowspan="1" colspan="1" |
&lt;!ELEMENT list '' ('' name, email'' ) &gt;''
| rowspan="1" colspan="1" |
&lt;list&gt;


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
Syntax for using an entity in an XML document:
: &amp;entity_name;


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
;Illustrations of entity definitions


&lt;/list&gt;
{| class="wikitable" 
! DTD rule
! XML example
| Result
|-
| <!ENTITY jt "Joe Test">
|  <para> &amp;jt; is here<para>
|  <para> Joe Test is here</para>
|-
| <!ENTITY space "&amp;#160;">
| &space;
|-
| <!ENTITY copyright "&amp;#xA9;">
| &amp;copyright; D. Schneider
| © D. Schneider
|-
| <!ENTITY explanation SYSTEM "project1a.xml">
|  <citation> &amp;explanation; </citation>
| <citation> .... contents of file project1a.xml inserted here ... </citation>
|}
|}


== 5.3 Combination rules for elements ==
=== Parameter entities ===
 
Most professional DTDs use parameter entities that are used to simplify DTD writing since complex DTDs often use same structures all over. Instead of typing these several times for each element definition, one can use an ENTITY construction like these:


{| border="1"
<source lang="xml">
! rowspan="1" colspan="1" |
<!ENTITY  % entity_name "content">
A and B = tags
<!ENTITY  % entity_name SYSTEM "URI">
! rowspan="1" colspan="1" |
</source>
Explanation
 
! rowspan="1" colspan="1" |
'''Example DTD entities defining reusable child elements'''
DTD example
! rowspan="1" colspan="1" |
XML example
|-
| rowspan="1" colspan="1" |
A , B
| rowspan="1" colspan="1" |
A followed by B
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


('' name ,email?'' )&gt;
<source lang="xml">
| rowspan="1" colspan="1" |
<!ENTITY % Content "(Para | List | Listing)*">
&lt;person&gt;
</source>


&lt;name&gt;Joe&lt;/name&gt;
Later in the DTD we then can build element definitions like this:


&lt;email&gt;x@x.x&lt;/email&gt;
<source lang="xml">
<!ELEMENT Intro (Title, %Content; ) >
<!ELEMENT Goal (Title, %Content; ) >
</source>


&lt;/person&gt;
The XML parser will then simply substitute these ''%Content;'' symbols and we get the following "real" DTD rules:
|-
| rowspan="1" colspan="1" |
A?
| rowspan="1" colspan="1" |
A is optional,


(it can be present or absent)
<source lang="xml">
| rowspan="1" colspan="1" |
<!ELEMENT Intro (Title, (Para | List | Listing)*) >
&lt;!ELEMENT person
<!ELEMENT Goal (Title, (Para | List | Listing)* ) >
</source>


(name, '' email?'' )&gt;
'''Example of a DTD entity declaration for a list of common attributes'''
| rowspan="1" colspan="1" |
&lt;person&gt;


&lt;name&gt;Joe&lt;/name&gt;&lt;/person&gt;
<source lang="xml">
|-
<!ENTITY % stamp '
| rowspan="1" colspan="1" |
  id ID #IMPLIED
A
  creation-day NMTOKEN #IMPLIED
| rowspan="1" colspan="1" |
  .......
At least one A
  mod-by NMTOKEN #IMPLIED
| rowspan="1" colspan="1" |
  version NMTOKEN #IMPLIED
&lt;!ELEMENT person
  status (draft|final|obsolete) #IMPLIED
  approval (ok|not-ok|so-so) #IMPLIED
  main-author CDATA #IMPLIED
  '>
</source>


(name, '' email '' )&gt;
ATTLIST definitions below use %stamp;
| rowspan="1" colspan="1" |
<source lang="xml">
&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
<!ELEMENT main-goal (title, content, (after-thoughts)?, (teacher-comments)?)>
<!ATTLIST main %stamp; >
<!ELEMENT title (...)>
<!ATTLIST main %stamp; >
</source>


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
== A complex text-centric example ==


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
'''Use case description'''


&lt;email&gt;x@x.x&lt;/email&gt;
Two DTDs that will help students write research projects and reports. Both include/use a HTML-like DTD to specify formating of element’s contents.
Do not worry if you don’t understand all the details, but we believe it’s important to demonstrate in this course some more "real life" examples


&lt;email&gt;x@y.x&lt;/email&gt;
We define two DTDs and reuse a third one in both


&lt;/person&gt;
* A DTD to define research projects:[http://tecfa.unige.ch/guides/xml/examples/dtd-examples/ePBL11/ePBLproject11.dtd ePBLproject11.dtd]
|-
* A DTD to structure research papers: [http://tecfa.unige.ch/guides/xml/examples/dtd-examples/ePBL11/ePBLpaper.dtd ePBLpaper11.dtd]
| rowspan="1" colspan="1" |
* [http://tecfa.unige.ch/guides/xml/examples/dtd-examples/ePBL11/ibtwsh6.dtd ibtwsh6.dtd] which is a mini XHTML that shows good usage of entities.
A*
| rowspan="1" colspan="1" |
Zero, one or several A
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


(name, '' email*'' )&gt;
Each of these DTDs only defines top-level "semantic tags" that define the essential structure of each document type. Elements then contain further markup that is just "stylistic" and taken from the XHTML specification.
| rowspan="1" colspan="1" |
&lt;person&gt;


&lt;name&gt;Joe&lt;/name&gt;
In these DTDs we include the ibtwsh6_ePBL DTD as an external entity like this:


&lt;/person&gt;
<! ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd" >
|-
%foreign-dtd;
| rowspan="1" colspan="1" |
A | B
| rowspan="1" colspan="1" |
Either A or B
| rowspan="1" colspan="1" |
&lt;!ELEMENT person


('' email | fax'' )&gt;
: For each tag in which we allow stylistic markup, we then can use constructs like:
| rowspan="1" colspan="1" |
&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
<!ELEMENT introduction %'''struct.model;'''>
<!ELEMENT conclusion %struct.model;>


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
=== The Itsy Bitsy Teeny Weeny Simple Hypertext DTD ===
'''ibtwsh.dtd''' is a popular mini XHTML that is used to "fill in" child elements of a semantically structured DTD. Here we present a slightly modified version that we used for DTDs to support project-oriented teaching as shown in the examples further down.
* [http://tecfa.unige.ch/guides/xml/examples/dtd-examples/ePBL11/ibtwsh6_ePBL.dtd http://tecfa.unige.ch/guides/xml/examples/dtd-examples/ePBL11/ibtwsh6_ePBL.dtd]


&lt;fax&gt;123456789&lt;/fax&gt;&lt;/person&gt;
<source lang="xml">
|-
<?xml version="1.0" encoding="ISO-8859-1"?>
| rowspan="1" colspan="1" |
(A, B)
| rowspan="1" colspan="1" |
Parenthesis will group and you can apply the above combination rules to the whole group
| rowspan="1" colspan="1" |
&lt;!ELEMENT list '' ('' name, email'' ) &gt;''
| rowspan="1" colspan="1" |
&lt;list&gt;


&lt;person&gt; &lt;name&gt;Joe&lt;/name&gt;
<!--
        WARNING: SLIGHTLY MODIFIED FOR USE AT TECFA ! GET THE ORIGINAL
        from http://www.ccil.org/%7Ecowan/XML/ibtwsh6.dtd


&lt;email&gt;x@x.x&lt;/email&gt;&lt;/person&gt;
ibtwsh.dtd
This is the Itsy Bitsy Teeny Weeny Simple Hypertext DTD.
Its public identifier is -//XML-DEV List//DTD IBTWSH 6.0//EN
The contents are dedicated to the public domain by
the author, John Cowan <cowan@ccil.org>, except that
John Cowan retains the moral right to be known as the author.
This is draft 6.0
03/04/2001 Changed by Vivian Synteta
Changes:
- Correct a mistake (LI)
- Add IDREF to element "A"
        - Take out id from entity all and IDREFS headers from tables and
          IDREF from element a
-->


&lt;/list&gt;
<!--
|}
======================================================================
This is an XML DTD which describes a subset of XHTML Basic for embedded
use within other XML DTDs.  It is by intention equivalent
(within its scope) to -//W3C//DTD XHTML 1.1//EN, but is
not a derived work in the copyright sense.  (Brief excerpts from
HTML 4.0 Transitional appear here and there.)


== Special contents ==
It is often convenient for XML documents to have a bit of
documentation somewhere in them.  In the absence of a DTD like
this one, that documentation winds up being #PCDATA only, which is
a pity, because rich text adds measurably to the readability of
documents.  By incorporating this DTD by reference (as an
external parameter entity) into another DTD, that DTD inherits
the capabilities of this one.  Using HTML-compatible elements
and attributes allows the documentation to be passed straight
through to HTML renderers.


{| border="1"
Current HTML renderers can cope with most XML tags, but empty
! rowspan="1" colspan="1" |
tags require special treatment.  Inserting a space before the
Special elements
terminating "/>" usually makes the "/" (which is not HTML)
! rowspan="1" colspan="1" |
invisible.  Using "<tag></tag>" is not as effective, as the
Explanation
latter is often misinterpreted as a second "<tag>".
! rowspan="1" colspan="1" |
DTD examples
! rowspan="1" colspan="1" |
XML example
|-
| rowspan="1" colspan="1" |
<nowiki>#PCDATA</nowiki>
| rowspan="1" colspan="1" |
"Parsed Character Data"


Text contents of an element. It should not contain any &lt;,&gt;,&amp; etc.
Note that since the elements of this DTD are intended to be
| rowspan="1" colspan="1" |
used within domain-specific elements of the surrounding DTD,
&lt;!ELEMENT email (#PCDATA)&gt;
it is not necessary that every fragment begin with an "html"
| rowspan="1" colspan="1" |
element, as in HTML.  Recommended content models for elements
&lt;email&gt;Daniel.Schneider@tecfa.unige.ch&lt;/email&gt;
containing documentation are "%horiz.model;" for simple
|-
text fragments and "%struct.model;" for documents in extenso.
| rowspan="1" colspan="1" |
ANY
| rowspan="1" colspan="1" |
Allows any non-specified child elements and parsed character data


(avoid this !!!)
Draft 6.0 is seriously incompatible with drafts 5.0 and earlier,
| rowspan="1" colspan="1" |
but *is* a subset of XHTML Basic.  I will keep draft 5.0 around;
&lt;!ELEMENT person ANY&gt;
note that I have changed the FPI.
| rowspan="1" colspan="1" |
======================================================================
&lt;person&gt;
-->


&lt;c&gt;text&lt;/c&gt;


&lt;a&gt;some &lt;b&gt;bbb&lt;/b&gt;
<!-- =========== Common attributes =========== -->


inside &lt;/a&gt;
<!-- All elements (except full-document elements) have these attributes -->
<!ENTITY % all "id  ID    #IMPLIED
                ref  IDREF #IMPLIED
        class CDATA #IMPLIED
title CDATA #IMPLIED">


&lt;/person&gt;
<!-- All non-empty elements have these attributes -->
|-
<!ENTITY % i18n "xml:lang CDATA #IMPLIED
| rowspan="1" colspan="1" |
dir (ltr|rtl) 'ltr'">
EMPTY
| rowspan="1" colspan="1" |
No contents
| rowspan="1" colspan="1" |
&lt;!ELEMENT br EMTPY&gt;
| rowspan="1" colspan="1" |
&lt;br/&gt;
|}


==== Note about Mixed Content ====
<!-- =========== Models =========== -->


* Mixed element contents contain both text and tags.
<!ENTITY % horiz "#PCDATA | a | abbr | acronym | br | cite | code |
dfn | em | img | kbd | q | samp | span |
strong | var">


&lt;para&gt; here is &lt;a href="xx"&gt;link&lt;/a&gt;. &lt;b&gt;Check&lt;/b&gt; it out &lt;/para&gt;
<!ENTITY % vert "address | blockquote | div | dl | h1 | h2 | h3 |
ol | p | pre | table | ul">


* You have to use the "|" construct for these
<!ENTITY % horiz.model "(%horiz;)*">
** Good examples:


&lt;!ELEMENT para (#PCDATA|a|ul|b|i|em)*&gt;
<!ENTITY % vert.model "(%horiz; | %vert;)*">


&lt;!ELEMENT p (#PCDATA | a | abbr | acronym | br | cite | code | dfn | em | img | kbd |
<!ENTITY % struct.model "(%vert;)*">


                        q | samp | span | strong | var )* &gt;


&lt;!ELEMENT p (#PCDATA | %font; | %phrase; | %special; | %form;)* &gt;
<!-- =========== Horizontal formatting elements =========== -->


** Bad examples:
<!-- Abbreviations (normal) -->
<!ELEMENT abbr %horiz.model;>
<!ATTLIST abbr %all;>


&lt;!ELEMENT p (name, first_name, #PCDATA)*&gt;
<!-- Acronyms (normal) -->
<!ELEMENT acronym %horiz.model;>
<!ATTLIST acronym %all;>


&lt;!ELEMENT p ( (#PCDATA) |a|ul|b|i|em)*&gt;
<!-- Citation (italics) -->
<!ELEMENT cite %horiz.model;>
<!ATTLIST cite
%all;>


== Defining attributes ==
<!-- Source code (monowidth) -->
<!ELEMENT code %horiz.model;>
<!ATTLIST code
%all;>


==== Rough syntax of Attribute rules: ====
<!--Terms being defined (normal) -->
<!ELEMENT dfn %horiz.model;>
<!ATTLIST dfn
%all;>


&lt;!ATTLIST element_name attr_name Attribute_type Type_Def Default &gt;
<!--Emphasis (italics) -->
<!ELEMENT em %horiz.model;>
<!ATTLIST em
%all;>


==== Overview: ====
<!--Keyboard input -->
<!ELEMENT kbd %horiz.model;>
<!ATTLIST kbd
%all;>


{| border="1"
<!-- Quotation (appropriate quotation marks) -->
! rowspan="1" colspan="1" |
<!ELEMENT q %horiz.model;>
Type
<!ATTLIST q
! rowspan="1" colspan="1" |
%all;
Attribute types
cite CDATA #IMPLIED>
|-
| rowspan="1" colspan="1" |
CDATA
| rowspan="1" colspan="1" |
"Character Data" - Text data
|-
| rowspan="1" colspan="1" |
NMTOKEN
| rowspan="1" colspan="1" |
A single word (no spaces or punctuations)
|-
| rowspan="1" colspan="1" |
ID
| rowspan="1" colspan="1" |
Unique identifier of the element.
|-
| rowspan="1" colspan="1" |
IDREF
| rowspan="1" colspan="1" |
Reference to an identifier.
|-
| rowspan="1" colspan="1" |
IDREFS
| rowspan="1" colspan="1" |
Reference to one or more identifiers
|-
| rowspan="1" colspan="1" |
(A|B|C|..)
| rowspan="1" colspan="1" |
List of values (from which the user must choose)
|}


{| border="1"
<!-- Sample output text (monowidth) -->
! rowspan="1" colspan="1" |
<!ELEMENT samp %horiz.model;>
<!ATTLIST samp
%all;>


! rowspan="1" colspan="1" |
<!-- Arbitrary span of text -->
Type Definition
<!ELEMENT span %horiz.model;>
|-
<!ATTLIST span
| rowspan="1" colspan="1" |
%all;>
<nowiki>#IMPLIED</nowiki>
| rowspan="1" colspan="1" |
Attribute is optional
|-
| rowspan="1" colspan="1" |
<nowiki>#REQUIRED</nowiki>
| rowspan="1" colspan="1" |
Attribute is mandatory)
|-
| rowspan="1" colspan="1" |
<nowiki>#FIXED Value</nowiki>
| rowspan="1" colspan="1" |
Attribute has a fixed value (user can't change it)
|}


=== Illustrations: ===
<!-- Strong emphasis (boldface) -->
<!ELEMENT strong %horiz.model;>
<!ATTLIST strong
%all;>


{| border="1"
<!-- Variable names (italics) -->
! rowspan="1" colspan="1" |
<!ELEMENT var %horiz.model;>
DTD rule
<!ATTLIST var
! rowspan="1" colspan="1" |
%all;>
example XML
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST person first_name CDATA #REQUIRED&gt;
| rowspan="1" colspan="1" |
&lt;person first_name="Joe"&gt;
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST person gender (male|female) #IMPLIED&gt;
| rowspan="1" colspan="1" |
&lt;person gender="male"&gt;
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST form method CDATA #FIXED "POST"&gt;
| rowspan="1" colspan="1" |
&lt;form method="POST"&gt;
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST list type (bullets|ordered) "ordered"&gt;
| rowspan="1" colspan="1" |
&lt;list type="bullets"&gt;
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST sibling type (brother|sister) #REQUIRED&gt;
| rowspan="1" colspan="1" |
&lt;sibling type="brother"&gt;
|-
| rowspan="1" colspan="1" |
&lt;!ATTLIST person id ID #REQUIRED&gt;
| rowspan="1" colspan="1" |
&lt;person id="N1004"&gt;
|}


==== Shortcut to define multiple attributes for an element: ====


&lt;!ATTLIST target_tag
<!-- IMGs added DKS -->
<!ELEMENT img EMPTY>
<!ATTLIST img
  src    CDATA  #REQUIRED
  alt    CDATA  #IMPLIED
  height  CDATA  #IMPLIED
  width  CDATA  #IMPLIED
  align  CDATA  #IMPLIED
  border  CDATA  #IMPLIED
  hspace  CDATA  #IMPLIED
  vspace  CDATA  #IMPLIED
  %all;>


attr1_nom TypeAttribut TypeDef Defaut


attr2_nom TypeAttribut TypeDef Defaut
<!-- Hypertext anchors.
CONSTRAINT: A elements are not allowed inside
other A elements, a fact that XML cannot express. -->
<!ELEMENT a %horiz.model;>
<!ATTLIST a
%all;
href  CDATA #IMPLIED
name  CDATA #IMPLIED
rel  CDATA #IMPLIED
rev  CDATA #IMPLIED
target (_BLANK | _TOP | _PARENT) #IMPLIED
>


...&gt;
<!-- Mandatory line breaks -->
<!ELEMENT br EMPTY>
<!ATTLIST br
%all;>


==== Shortcut illustrations: ====
<!-- =========== Headers =========== -->


&lt;!ATTLIST person  ident ID              #REQUIRED  gender male|female)    #IMPLIED  nom      CDATA            #REQUIRED  prenom    CDATA            #REQUIRED  relation  brother|sister)  #REQUIRED &gt;  &lt;!ATTLIST portable      owner  IDREF            #REQUIRED &gt;
<!ELEMENT h1 %horiz.model;>
<!ATTLIST h1
%all;>


<!ELEMENT h2 %horiz.model;>
<!ATTLIST h2
%all;>


=== Example 5-1: Lone family DTD (file family.dtd) ===
<!ELEMENT h3 %horiz.model;>
<!ATTLIST h3
%all;>


[[Image:xml-intro-edit-10.png]]


==== A valid XML file ====
<!-- =========== Lists =========== -->


&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;
<!-- Definition list -->
<!ELEMENT dl (dt|dd)+>
<!ATTLIST dl
%all;>


&lt;!DOCTYPE family SYSTEM "family.dtd"&gt;
<!-- Defined term -->
<!ELEMENT dt %horiz.model;>
<!ATTLIST dt
%all;>


&lt;family&gt;
<!-- Definition -->
<!ELEMENT dd %horiz.model;>
<!ATTLIST dd
%all;>


  &lt;person name="Joe Miller" gender="male"
<!-- Ordered list -->
<!ELEMENT ol (li)+>
<!ATTLIST ol
%all;>


          type="father" id="N123456789"/&gt;
<!-- Unordered list -->
<!ELEMENT ul (li)+>
<!ATTLIST ul
%all;>


  &lt;person name="Josette Miller" gender="female"
<!-- List element -->
<!ELEMENT li %horiz.model;>
<!ATTLIST li
%all;>


          type="girl" id="N123456987"/&gt;


&lt;/family&gt;


</div></div></div><div>
<!-- =========== Basic table support =========== -->


== 5.6 General entities ==
<!-- Shared attributes -->
<!ENTITY % aligns
"align (left | center | right | justify) #IMPLIED
valign (top | middle | bottom | baseline) #IMPLIED">


Consider entities as abbreviations for some other content. An entity must be defined in the DTD and its contents are substituted when encountered in the XML file.
<!-- Table -->
<!ELEMENT table (caption?, tr+)>
<!ATTLIST table
%all;
border      CDATA #IMPLIED
cellpadding CDATA #IMPLIED
cellspacing CDATA #IMPLIED
summary    CDATA #IMPLIED
width      CDATA #IMPLIED>


** Recall that XML initially only defines 5 entities and that HTML does many more...
<!-- Table caption -->
** Use the '' &amp;lt; &amp;amp; &amp;gt; &amp;aquot; &amp;apos;'' entities to refer to '' &lt;, &amp;, &gt;,"'' '' '' and'' '' '' '''
<!ELEMENT caption %horiz.model;>
<!ATTLIST caption
%all;>


Syntax of an internal entity definition: '' &lt;!ENTITY entity_name "content"&gt;''
<!-- Table row -->
<!ELEMENT tr (th | td)+>
<!ATTLIST tr
%all;
%aligns;>


Syntax of an external entity definition: '' &lt;!ENTITY entity_name SYSTEM URI&gt;''
<!-- Table header -->
<!ELEMENT th %vert.model;>
<!ATTLIST th
%all;
%aligns;
abbr    CDATA #IMPLIED
axis    CDATA #IMPLIED
colspan CDATA "1"
rowspan CDATA "1"
scope  CDATA #IMPLIED>


Syntax of using an entity:'' &amp;entity_name;''
<!-- Table data -->
<!ELEMENT td %vert.model;>
<!ATTLIST td
%all;
%aligns;
abbr    CDATA #IMPLIED
axis    CDATA #IMPLIED
colspan CDATA "1"
rowspan CDATA "1"
scope  CDATA #IMPLIED>


<div>


==== Illustrations of entity definitions: ====
<!-- =========== Other vertical elements =========== -->


{| border="1"
<!-- Address block -->
! rowspan="1" colspan="1" |
<!ELEMENT address %horiz.model;>
DTD rule
<!ATTLIST address
! rowspan="1" colspan="1" |
%all;>
XML example
! rowspan="1" colspan="1" |
Result
|-
| rowspan="1" colspan="1" |
&lt;!ENTITY jt "Joe Test"&gt;
| rowspan="1" colspan="1" |
'' &lt;para&gt; &amp;jt; is here&lt;para&gt;''
| rowspan="1" colspan="1" |
'' &lt;para&gt; Joe Test is here&lt;/para&gt;''
|-
| rowspan="1" colspan="1" |
&lt;!ENTITY space "&amp;#160;"&gt;
| rowspan="1" colspan="1" |


| rowspan="1" colspan="1" |
<!-- Block quotation -->
<!ELEMENT blockquote %struct.model;>
<!ATTLIST blockquote
%all;
cite CDATA #IMPLIED>


|-
<!-- General text division -->
| rowspan="1" colspan="1" |
<!ELEMENT div %struct.model;>
&lt;!ENTITY copyright "&amp;#xA9;"&gt;
<!ATTLIST div
| rowspan="1" colspan="1" |
%all;>
&amp;copyright; D. Schneider
| rowspan="1" colspan="1" |


|-
<!-- Paragraph -->
| rowspan="1" colspan="1" |
<!ELEMENT p %horiz.model;>
&lt;!ENTITY explanation SYSTEM "project1a.xml"&gt;
<!ATTLIST p
| rowspan="1" colspan="1" |
%all;>
'' &lt;citation&gt; &amp;explanation; &lt;/citation&gt;''
| rowspan="1" colspan="1" |
&lt;citation&gt; '' contents of project1a.xml ...'' &lt;/citation&gt;
|}


</div></div><div>
<!-- Preformatted text -->
<!ELEMENT pre %horiz.model;>
<!ATTLIST pre
%all;>


== 5.7 Parameter entities ==
<!-- =========== END OF ibtwsh.dtd =========== -->
</source>


* Most professional DTDs use parameter entities.
=== ePBL Project ===
* These are used to simplify DTD writing


&lt;!ENTITY '' %'' entity_name "content"&gt;<br /> &lt;!ENTITY '' %'' entity_name SYSTEM "URI"&gt;
This DTD allows to define an exploratory student research project and also to keep track of progress by updating certain elements. Other versions were made for projects in experimental psychology.


<div>
<source lang="xml">
<?xml version="1.0" encoding="ISO-8859-1" ?>


=== Example 5-2: DTD entities to define reusable child elements ===
<!-- ___________________________________________ _____________________  -->
<!-- ePBL-project DTD for student project management & specification    -->
<!--  Copyright: (2004) Paraskevi.Synteta@tecfa.unige.ch         -->
<!--              http://tecfa.unige.ch/~paraskev/                      -->
<!--                            Daniel K. Schneider            -->
<!--              http://tecfa.unige.ch/tecfa-people/schneider.html    -->
<!--  Created: 13/11/2002 (based on EVA_pm grammar)            -->
<!--  Updated: 07/05/2004         -->
<!-- VERSIONS         -->
<!-- v1.1 Adaptations to use with Morphon xml editor and addition of IDs-->
<!-- v1.1b fixed vert.model to struct.model / DKS 2004                  -->
<!-- _________________________________________________________________  -->


* More complex DTD often use same structures all over. Instead of typing these several times for each element definition, one can use an ENTITY construction like this:
<!-- _______________________ ENTITY DECLARATIONS _____________________  -->


Â
<!ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd">
%foreign-dtd;


&lt;!ENTITY % Content "(Para | List | Listing)*"&gt;
<!ENTITY % id  "id  ID    #IMPLIED">


  Â
<!-- _______________________ MAIN ELEMENT  _______________________ -->
<!ELEMENT project  (name, authors, date, updated, goal, state-of-the-art,
                    research-development-questions, methodology, workpackages ) >


Later in the DTD we then can have element definitions like this:
<!ELEMENT name  (#PCDATA )>


Â
<!ELEMENT date (#PCDATA )>


&lt;!ELEMENT Intro (Title, %Content; ) &gt;
<!ELEMENT authors (#PCDATA )>


&lt;!ELEMENT Goal (Title, %Content; ) &gt;
<!ELEMENT updated (#PCDATA )>


Â
<!ELEMENT goal (title, description )>


The XML parser will then simply translate these '' %Content;'' and we get:
<!ELEMENT state-of-the-art  %struct.model;>
<!ATTLIST state-of-the-art  %id;>


Â
<!ELEMENT research-development-questions (question )+>
<!ELEMENT question (title, description )>


  &lt;!ELEMENT Intro (Title, (Para | List | Listing)*) &gt;
<!ELEMENT methodology %struct.model;>
<!ATTLIST methodology  %id;>


&lt;!ELEMENT Goal (Title, (Para | List | Listing)* ) &gt;
<!ELEMENT workpackages (workpackage )+>
<!ELEMENT workpackage (planning, objectives, deliverables )>
<!ATTLIST workpackage  %id;>


Â
<!ELEMENT objectives (objective )+>
<!ELEMENT objective (title, description )>


</div><div>
<!ELEMENT deliverables (deliverable )+>
<!ELEMENT deliverable (url, title, description )>
<!ELEMENT url  (#PCDATA )>


=== Example 5-3: DTD entities to define reusable attribute definitions ===
<!ELEMENT planning (from, to, hours-of-work?, progress )>
<!ELEMENT from  (#PCDATA )>
<!ELEMENT to (#PCDATA )>
<!ELEMENT hours-of-work  (#PCDATA )>
<!ELEMENT progress  (#PCDATA )>
<!-- ____________________________________________________________ -->


* You may use the same procedure to define "bricks" for attribute definitions
<!ELEMENT title  (#PCDATA )>
* Entity example that defines part of an attribute definition
<!ATTLIST title  %id;>


&lt;!ENTITY ''% stamp ''
<!ELEMENT description %struct.model;>
<!-- ____________________________________________________________ -->
'
</source>


  id ID #IMPLIED
=== ePBL paper ===


  creation-day NMTOKEN #IMPLIED
We used several versions of this, depending on the nature of the paper we wanted the students to produce.


  .......
<source lang="xml">
<?xml version="1.0" encoding="ISO-8859-1"?>


  mod-by NMTOKEN #IMPLIED
<!-- ___________________________________________ _____________________  -->
<!-- ePBL-paper DTD for student project management & specification      -->
<!--  Copyright: (2004) Paraskevi.Synteta@tecfa.unige.ch         -->
<!--              http://tecfa.unige.ch/~paraskev/                      -->
<!--                            Daniel K. Schneider            -->
<!--              http://tecfa.unige.ch/tecfa-people/schneider.html    -->
<!--  Created: 13/11/2002 (based on EVA_paper grammar)            -->
<!--  Updated: 07/05/2004         -->
<!-- VERSIONS         -->
<!-- v1.1 Adaptation to use with Morphon xml editor and add IDs, IDREFs -->
<!-- v1.1b fixed vert.model to struct.model / DKS 2004                  -->
<!-- SEE ALSO the book.dtd made by DKS that is simply a superset        -->
<!-- _________________________________________________________________  -->


   version NMTOKEN #IMPLIED
<!ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd">
<!ENTITY % id  "id  ID   #REQUIRED">


  status (draft|final|obsolete) #IMPLIED
<!-- _________________________ content ________________________________ -->
   
%foreign-dtd;


  approval (ok|not-ok|so-so) #IMPLIED
<!ELEMENT paper ( info, abstract, (preface)?, introduction, main, conclusion, references, (annex)?, (aknowledgements)? ) >


  main-author CDATA #IMPLIED
<!ELEMENT info  ( title, authors, date, updated, keywords )>
<!ELEMENT title (#PCDATA )>
<!ELEMENT authors (author )+>
<!ELEMENT author (firstname, familyname, homepageurl, email )>
<!ELEMENT firstname (#PCDATA )>
<!ELEMENT familyname (#PCDATA )>
<!ELEMENT homepageurl (#PCDATA )>
<!ATTLIST homepageurl %all;>
<!ELEMENT email (#PCDATA )>


'
<!ELEMENT date (#PCDATA )>
<!ELEMENT updated (#PCDATA )>
<!ELEMENT keywords (keyword )+>
<!ELEMENT keyword (#PCDATA )>


&gt;
<!ELEMENT abstract (#PCDATA )>


ATTLIST definitions below use %stamp;
<!ELEMENT preface %struct.model;>


&lt;!ELEMENT main-goal (title, content, (after-thoughts)?, (teacher-comments)?)&gt;
<!ELEMENT introduction %struct.model;>


&lt;!ATTLIST main ''%stamp;''
<!ELEMENT main %struct.model;>
  &gt;


&lt;!ELEMENT title (...)&gt;
<!ELEMENT conclusion %struct.model;>


&lt;!ATTLIST main ''%stamp;''
<!ELEMENT references (reference )+>
  &gt;
<!ELEMENT reference %struct.model;>
<!ATTLIST reference %all;>


Â
<!ELEMENT annex %struct.model;>


</div></div><div>
<!ELEMENT aknowledgements %struct.model;>
</source>


== 5.8 Some advice for designing DTDs ==
== Some advice for designing DTDs ==


<div>
=== General advice ===


==== Don't forget elements and be liberal ====
; Don't forget elements and be liberal


* Each element needs to be defined, but only once !
* Each element needs to be defined, but only once !
* Only make elements mandatory if they really are wanted, else use e.g. '' element'' '' ?''
* Only make elements mandatory if they really are wanted, i.e. make the others optional, e.g. by using the "?" as in ''element?''
 
</div><div>


==== Plan the global structure ====
; Plan the global structure


* Before you start writing out DTDs, use some simple "language" to draft the structure, e.g. use a notation like:
* Before you start writing out DTDs, use some simple "language" to draft the structure, e.g. use a notation like:


  name ==&gt; family   given
  name   ==family given
 
  family ==> "text"
  family ==&gt; "text"


* In most cases, each "object" of your "information domain" becomes an element
* In most cases, each "object" of your "information domain" becomes an element
** Use child elements to model components
* Use child elements to model components
** Use attributes to describe properties of components
* Use attributes to describe properties of components


</div><div>
; Start from the root element and work your way down
 
==== Start from the root element and work your way down: ====


# Root element
# Root element
# Child elements of root element
# Child elements of root element
# Child elements of the other elements, etc.
# Child elements of the other elements, etc.
=== Attributes vs. Elements ===
* There are some design rules that may help you decide whether using an element or an attribute
* In case of doubt, always use elements ...
; Rather use child elements inside an element to represent an information block
* if order is important (attributes can't be ordered)
* if you plan to use the same kind of information block with different parents
* if a future version of DTD may specify sub-components of an information block
* if the information block represents a "thing" (an object in OO programming)
* if the DTD is text-centric, because an author must see contents she/he edits and attributes are often hidden away in XML editors; only use attributes to qualify properties like style !
; Rather use attributes to represent an information block
* if an attribute refers to an other element:
: <nowiki><pet_of owner_name="lisa" pet_type="cat"></nowiki> would refer to <nowiki><animal category="cat"></nowiki>
* to declare usage/type/etc. of an element:
: <source lang="xml">
<address usage="prof"> ... </address></source>
* if you wish to list all possible values a user can enter
* if you want to restrict data type of the attribute value (e.g. require a single word)


[[Category: XML]]
[[Category: XML]]
[[Category: Standards]]
[[Category: Standards]]
[[Category: Tutorials]]
[[Category:Web technology tutorials]]

Latest revision as of 14:52, 21 January 2020

Introduction

This is a short tutorial about creating simple DTDs (Document Type Definitions).

Learning goals

  • Be able to read a DTD
  • Be able to create a simple DTD with nested elements, i.e. understand combination features
  • Be able to define attributes for elements
  • Know how to create and use DTD entities

Prerequisites

Next steps

Executive overview

DTD grammars are a set of rules that define:

  1. a set of elements (tags) and their attributes that can be used to create an XML document;
  2. how these elements can be combined/embedded ;
  3. different sorts of entities (reusable fragments, special characters).

DTDs can't define element content types, i.e. what text can go inside elements. Most attribute can't be typed either. For example, with a DTD one cannot specify that input should be a number from 0 to 100..

XML Principles recalled

Specification of a markup language

There are many ways of defining a XML language. You could write down the specification of an XML vocabulary in simple prose, or use a so-called Schema language, or finally, a combination of the two. The most simple schema language, i.e. DTDs, is defined in the XML Standard.

DTD stands for Document Type Definition. A DTD is a set of rules that constitute a grammar (also called schema) that defines the so-called XML application also called XML vocabular. For example, the file xhtml1-transitional.dtd available at through the XHTML 1.0 specification page, formally defines the grammar for the XHTML 1 web markup language.

  • The most important part of a DTD-based markup language is usually the DTD itself, but in addition other constraints can be added in a design document.
  • The DTD does not identify the root element ! You will have to tell the users what elements can be root elements.
  • Since DTDs can't express data constraints, write them out in a specification document, e.g. "the value of length attribute is a string composed of a number plus "cm" or "inch" or "em". Examples:
 <size length="10cm">
 <size length="3inch">

Example 1: A simple DTD

 <!ELEMENT page  (title, content, comment?)>
 <!ELEMENT title (#PCDATA)>
 <!ELEMENT content (#PCDATA)>
 <!ELEMENT comment (#PCDATA)>

A DTD document contains just rules and no XML declaration is needed ... more details later ...

Associating a DTD with an XML document

Before we learn how to create our own grammars, let's shortly recall how how to associate a DTD with an XML file. For more details, please read the Editing XML tutorial.

  • In the XML file, you can add a declaration that specifies the DTD and that implicitly requires that XML contents must be validated.
  • This DTD file is declared on top of the file after the XML declaration.
  • XML declarations, DTD declaration etc. are part of the prologue
Example XML contents with a DTD declaration
 <?xml version="1.0" ?>
 <!DOCTYPE hello SYSTEM "hello.dtd">

 <hello>Here we <strong>go</strong> ... </hello>

Let us recall from the editing XML tutorial, that there are four ways of using a DTD

(1) No DTD

  • XML document will just be well-formed, or validation takes place in some other contexts, e.g. there exist tools that allow you to find out if a given XML document is valid with respect to a given DTD file)

(2) DTD rules are defined inside the XML document

  • We get a "standalone" document (the XML document is self-sufficient)

(3) "Private/System" DTDs

  • As shown in the example above, the DTD is located on the system (own computer or the Internet). That's what you are going to use when you write your own DTDs.

(4) Public DTDs

  • we use a name for the DTD. This means that both your XML editor and user software know the DTD. This is the strategy used for common Web DTDs like XHTML, SVG, MathML, etc.

Finally, let us recall that other schema formalism than DTDs exist, e.g. XML Schema.

Sample XML documents with DTD declarations

Example 1 - Hello XML without DTD
 <?xml version="1.0" standalone="yes"?>
 <hello> Hello XML et hello cher lecteur ! </hello>
Example 2 - Hello XML with an internal DTD
  <?xml version="1.0" standalone="yes"?>
  <!DOCTYPE hello [
     <!ELEMENT hello (#PCDATA)>
     ]>

  <hello> Hello XML et hello dear readers ! </hello>
Example 3 - Hello XML with an external DTD
That's what you should with your own home-made DTDs
 <?xml version="1.0" ?>
 <!DOCTYPE hello SYSTEM "hello.dtd">
 <hello> This is a very simple XML document </hello>
Example 4 - XML with a public external DTD (RSS 0.91)
 <?xml version="1.0" ?>
 <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
  "http://my.netscape.com/publish/formats/rss-0.91.dtd">
 <rss version="0.91">
 <channel> ...... </channel>
 </rss>

Understanding DTDs by example

Recall that DTDs define all the elements and attributes and the way they can be combined

Example 6: Hello text with XML

A simple XML document of type <page>
 <?xml version="1.0"?>
 <page>
  <title>Hello friend</title>
  <content>Here is some content :)</content>
  <comment>Written by DKS/Tecfa, adapted from S.M./the Cocoon samples</comment>
 </page>
A DTD that would validate this "page" document

Xml-intro-edit-6.png

Example 7: A recipe list in XML

  • Source: Introduction to XML by Jay Greenspan (now dead URL)
  <?xml version="1.0"?>
  <!DOCTYPE list SYSTEM "simple_recipe.dtd">
  <list>
  <recipe>
    <author>Carol Schmidt</author>
    <recipe_name>Chocolate Chip Bars</recipe_name>
    <meal>Dinner</meal>
    <ingredients>
      <item>2/3 C butter</item>      <item>2 C brown sugar</item>
      <item>1 tsp vanilla</item>     <item>1 3/4 C unsifted all-purpose flour</item>
      <item>1 1/2 tsp baking powder</item>
      <item>1/2 tsp salt</item>      <item>3 eggs</item>
      <item>1/2 C chopped nuts</item>
      <item>2 cups (12-oz pkg.) semi-sweet choc. chips</item>
    </ingredients>
    <directions>
 Preheat oven to 350 degrees. 
 Melt butter; combine with brown sugar and vanilla in large mixing bowl. 
 Set aside to cool. Combine flour, baking powder, and salt; set aside. 
 Add eggs to cooled sugar mixture; beat well. 
 Stir in reserved dry ingredients, nuts, and chips. 
 Spread in greased 13-by-9-inch pan.
 Bake for 25 to 30 minutes until golden brown; cool.  Cut into squares.
    </directions>
  </recipe>
 </list>
Contents of the DTD

Xml-intro-edit-7.png

Example 8: A simple story grammar

 <?xml version="1.0" "?>
 <!-- DTD to write simple stories
      Made by Daniel K. Schneider / TECFA / University of Geneva
      VERSION 1.0
      30/10/2003 -->
 <!ELEMENT STORY (title, context, problem, goal, THREADS, moral, INFOS)>
 <!ATTLIST STORY xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
 <!ELEMENT THREADS (EPISODE+)>
 <!ELEMENT EPISODE (subgoal, ATTEMPT+, result) >
 <!ELEMENT ATTEMPT (action | EPISODE) >
 <!ELEMENT INFOS ( ( date | author | a )* ) >
 <!ELEMENT title (#PCDATA) >
 <!ELEMENT context (#PCDATA) >
 <!ELEMENT problem (#PCDATA) >
 <!ELEMENT goal (#PCDATA) >
 <!ELEMENT subgoal (#PCDATA) >
 <!ELEMENT result (#PCDATA) >
 <!ELEMENT moral (#PCDATA) >
 <!ELEMENT action (#PCDATA) >
 <!ELEMENT date (#PCDATA) >
 <!ELEMENT author (#PCDATA) >
 <!ELEMENT a (#PCDATA)>
 <!ATTLIST a
      xlink:href CDATA #REQUIRED
      xlink:type CDATA #FIXED "simple">
Here is a valid skeleton
  <?xml version="1.0" " ?>
  <!DOCTYPE STORY SYSTEM "story-grammar.dtd">
  <?xml-stylesheet href="story-grammar.css" type="text/css"?>
  <STORY>
   <title>The little XMLer</title>
   <context></context>
  <problem></problem>
  <goal></goal>
  <THREADS>
    <EPISODE>
      <subgoal>I have to do it ...</subgoal>
      <ATTEMPT>
        <action></action>
      </ATTEMPT>
      <result></result>
    </EPISODE>
  </THREADS>
  <moral></moral>
  <INFOS>
  </INFOS>
 </STORY>

The picture gives some extra information

Xml-intro-edit-8.png

Example 9: Lone family DTD

Xml-intro-edit-9.png

A valid XML file
 <?xml version="1.0" ?>
 <!DOCTYPE family SYSTEM "family.dtd">
 <family>
   <person name="Joe Miller" gender="male"
           type="father" id="123.456.789"/>
   <person name="Josette Miller" gender="female"
           type="girl" id="123.456.987"/>
 </family>

Example 10: RSS

  • There are several RSS standards. RSS 0.91 is Netscape's original (still being used)
 <!ELEMENT rss (channel)>
 <!ATTLIST rss version CDATA #REQUIRED>
  <!-- must be "0.91"> -->
  <!ELEMENT channel (title | description | link | language | item  | rating? | image? | textinput? | 
               copyright? | pubDate? | lastBuildDate? | docs? | managingEditor? | 
               webMaster? | skipHours? | skipDays?)*>
  <!ELEMENT title (#PCDATA)>
  <!ELEMENT description (#PCDATA)>
  <!ELEMENT link (#PCDATA)>
  <!ELEMENT image (title | url | link | width? | height? | description?)*>
  <!ELEMENT url (#PCDATA)>
  <!ELEMENT item (title | link | description)*>
  <!ELEMENT textinput (title | description | name | link)*>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT rating (#PCDATA)>
  <!ELEMENT language (#PCDATA)>
  <!ELEMENT width (#PCDATA)>
  <!ELEMENT height (#PCDATA)>
  <!ELEMENT copyright (#PCDATA)>
  <!ELEMENT pubDate (#PCDATA)>
  <!ELEMENT lastBuildDate (#PCDATA)>
  <!ELEMENT docs (#PCDATA)>
  <!ELEMENT managingEditor (#PCDATA)>
  <!ELEMENT webMaster (#PCDATA)>
  <!ELEMENT hour (#PCDATA)>
  <!ELEMENT day (#PCDATA)>
  <!ELEMENT skipHours (hour )>
  <!ELEMENT skipDays (day )>
Possible XML document for RSS
  <?xml version="1.0" " ?>
  <!DOCTYPE rss SYSTEM "rss-0.91.dtd">
  <rss version="0.91">
     <channel>
       <title>Webster University</title>
       <description>Home Page of Webster University</description>
       <link>http://www.webster.edu</link>
       <item>
	 <title>Webster Univ. Geneva</title>
	 <description>Home page of Webster University Geneva</description>
	 <link>http://www.webster.ch</link>
       </item>
       <item>
	 <title>http://www.course.com/</title>
	 <description>You can find Thomson text-books materials (exercise data) on this web site</description>
	 <link>http://www.course.com/</link>
       </item>
     </channel>
   </rss>

Definition of elements

Le us recall what DTD grammars are supposed to do. DTDs define

  1. a set of elements (tags) and their attributes that can be used to create an XML document;
  2. and define how elements can be embedded;

In addition, a DTD may define different sorts of entities (reusable fragments) and attribute types for elements. We shall explain the use of attributes and entities below.

Syntax of a DTD rule to define elements:

 <!ELEMENT tag_name (child_element_specification) >

child_element_specification may contain:

  • A combination of child elements according to combination rules that we will introduce below.
 <!ELEMENT page  (title, content, comment?)>
  • Mixed contents, i.e. child elements mixed with data (#PCDATA)
important: The #PCDATA element must come first !
 <!ELEMENT para (#PCDATA | strong)*>
  • #PCDATA (Just data)
 <!ELEMENT title (#PCDATA)>
  • ANY (only used during development)
 <!ELEMENT para (ANY)*>
  • EMPTY (the element has no contents)
 <!ELEMENT person EMPTY>

Tag names

Each tag name must start with a letter or an underscore ('_')
followed by letters, numbers or the following characters: '_' , '-', '.', ':'

Bad examples

 <!ELEMENT 1st ...>
 <!ELEMENT My Home ...>

Good examples:

 <!ELEMENT First ...>
 <!ELEMENT My_Home ...>

Combination rules

By using the combination rules an information architect (you!) defines how elements can be combined, i.e. mandatory and optional child elements, order of elements, and repetition.

Each and every element in your language must be defined with an <!ELEMENT > rule


A and B = tags Explanation DTD examples XML examples
A , B A followed by B

Elements in that order

 <!ELEMENT person
           ( name ,email? )>
 <!ELEMENT Name
           (First, Middle, Last)>
<person>
 <name>Joe</name>
 <email>x@x.x</email>
</person>
<Name>
 <First>D.</First>
 <Middle>K.</Middle>
 <Last>S.</Last>
</Name>
A? A is optional,

(it can be present or absent)

 <!ELEMENT person 
           (name,  email? )>
 <!ELEMENT Name
           (First,Middle?,Last)>
 <person>
  <name>Joe</name>
</person>
<Name>
 <First>D.</First>
 <Last>S.</Last>
</Name>
A+ At least one A
 <!ELEMENT person
           (name,  email+ )>
 <!ELEMENT list 
           (movie+)
 <person> <name>Joe</name>
   <email>x@x.x</email></person>
 <person> <name>Joe</name>
   <email>x@x.x</email>
   <email>x@y.x</email>
 </person>
 <list>
    <movie>Return of ...</movie>
    <movie>Comeback of ...</movie> 
 </list>
A* Zero, one or several A
  <!ELEMENT person 
           (name,  email* )>
  <!ELEMENT list
            (item*)
<person>
  <name>Joe</name>
</person>
  <list>
   <item>Return of ...</item>
  </list>
A | B Either A or B
 <!ELEMENT person 
          ( email | fax )>
 <!ELEMENT major 
           (economics | law)>
<person> <name>Joe</name>
  <email>x@x.x</email>
</person>

<person> <name>Joe</name>
  <fax>123456789</fax>
</person>
<major> 
   <economics> </economics>
 /major>
(A, B) Parenthesis will group and you can

apply the above combination rules to the whole group

  <!ELEMENT text 
            (para | list | title)*>
<text>
 <title>Story</title>
 <para>Once upon a time</para> 
 <title>The awakening</title> 
 <list> ... </list>
</text>

Contents of DTD elements

As explained above, DTDs allow to define four different kinds of XML elements with respect to their content. XML elements can either include just other elements, just data (no elements), so-called mixed contents, or no data. We illustrate this with examples:

(1) Child elements only

<ul>
 <li>Item 1</li>
 <li>Item 2</li><li>Item 3</li>
</ul>

(2) Data only

<para>Here we go</para>

(3) Mixed contents, i.e. both data and elements

<para>Here we go <bold>fast</bold></para>

(4) Empty elements

 <newline/>

The following table summarizes how DTDs allow to define element contents other than combinations of child elements.

Special elements Explanation DTD examples XML example
#PCDATA "Parsed Character Data"

Text contents of an element. It should not contain any <,>,& etc.

<!ELEMENT email (#PCDATA)>
 <email>Daniel.Schneider@nowhere.org</email>
ANY Allows any non-specified child elements and parsed character data

(avoid this !!!)

<!ELEMENT person ANY>
 <person>
   <c>text</c>
   <a>some <b>bbb</b>inside</a>
 </person>
EMPTY No contents <!ELEMENT br EMTPY> <br/>

Mixed element contents contain both text and tags (elements)

Example:

 <para> here is a <a href="xx">link</a>. <b>Check</b> it out </para>

To allow for these mixed contents, one must , as shown in the good examples below.

  • use the "|" construct for listing the alternatives
  • Make it repeatable using the (....)* construct.
  • specify #PCDATA first
Good examples
 <!ELEMENT para (#PCDATA|a|ul|b|i|em)* >  
 <!ELEMENT p (#PCDATA | a | abbr | acronym | br | cite | code | dfn | em | img | kbd |
           q | samp | span | strong | var )* >  
 <!ELEMENT par (#PCDATA | %font; | %phrase; | %special; | %form;)* >
Bad examples
 <!ELEMENT p (name, first_name, #PCDATA)*>
 <!ELEMENT p (name | first_name | #PCDATA)*>  <!-- #PCDATA is not first -->
 <!ELEMENT p ( (#PCDATA) |a|ul|b|i|em)*>

Defining attributes

Usually an object is defined in terms of its properties and its contents. Translated to XML, objects are usually represented as elements and its properties as attributes. However properties also could be expressed with child elements and the other way round...

Rough syntax of Attribute rules:

<!ATTLIST element_name attr_name Attribute_type Type_Definition Default >

Here are some XML elements with attributes

<img src="picture.png"/>
<person name="Joe Miller" gender="male" type="father" id="N123456789"/>
<a href="http://no.com/bla">no company</a>

When we define such attributes we always start with the same pattern:

 <!ATTLIST name_of_element name_of_attribute ... >

for example

 <!ATTLIST person name ...>

We then must provide an attribute type using a keyword. There exist six attribute types: normal text, single word, an ID, a (or more) reference(s) to an ID of another attribute, and a list of values. These types are summarized in the following table.

Keyword Attribute types
CDATA "Character Data" - Text data
NMTOKEN A single word (no spaces or punctuations)
ID Unique identifier of the element.
IDREF Reference to an identifier.
IDREFS Reference to one or more identifiers
(A|B|C|..) List of values (from which the user must choose)

Finally, we have to decide whether an attribute is mandatory, optional or fixed.

Keyword Type Definition
#IMPLIED Attribute is optional
#REQUIRED Attribute is mandatory
#FIXED Value Attribute has a fixed value (user can't change it)

Below are some illustrations of valid attribute definitions

DTD rule example XML
<!ATTLIST person first_name CDATA #REQUIRED>
<person first_name="Joe">
<!ATTLIST person gender (male|female) #IMPLIED>
<person gender="male">
<!ATTLIST form method CDATA #FIXED "POST">
<form method="POST">
<!ATTLIST list type (bullets|ordered) "ordered">
<list type="bullets">
<!ATTLIST sibling type (brother|sister) #REQUIRED>
<sibling type="brother">
<!ATTLIST person id ID #REQUIRED>
<person id="N1004">

Shortcut to define multiple attributes for an element:

Instead of defining each attribute with a different instruction, you can define all attributes for an element with a single one.

<!ATTLIST target_tag
          attr1_nom TypeAttribut TypeDef Defaut
          attr2_nom TypeAttribut TypeDef Defaut
 ...>
Example
 <!ATTLIST person ident ID #REQUIRED 
      gender (male|female) #IMPLIED
      nom CDATA #REQUIRED 
      prenom CDATA #REQUIRED   
      relation  brother|sister) #REQUIRED >  
 <!ATTLIST portable owner IDREF #REQUIRED >

Example: Lone family DTD (file family.dtd)

Xml-intro-edit-10.png

A valid family XML file
 <?xml version="1.0" ?>
 <!DOCTYPE family SYSTEM "family.dtd">
 <family>
   <person name="Joe Miller" gender="male"
           type="father" id="N123456789"/>
   <person name="Josette Miller" gender="female"
           type="girl" id="N123456987"/>
 </family>

ID, IDREF and IDREFS

Attributes of type ID, IDREF and IDREFS are checked for validity. That means:

  • Each ID value must be unique and start with a letter
  • Each IDREF value IDREFS list of values must point to an element with an existing ID value.

Below is an XML (standalone) example that demonstrates use of an ID an IDREF, and an IDREFS attribute in order to create links between persons.

<?xml version = "1.0"?>
<!DOCTYPE Folks [
	<!ELEMENT Folks (Person*)>
	<!ELEMENT Person (Name,Email?)>
	<!ATTLIST Person Pin ID #REQUIRED>
	<!ATTLIST Person Friend IDREF #IMPLIED>
	<!ATTLIST Person Likes IDREFS #IMPLIED>
	<!ELEMENT Name (#PCDATA)>
	<!ELEMENT Email (#PCDATA)>
	]>
<Folks>
    <Person Pin = "N1">
      <Name>Someone</Name>
    </Person>

    <Person Pin = "N2" Friend = "N1">
      <Name>Someone else</Name>
    </Person>
    
    <Person Pin = "N3" Likes = "N2 N1">
      <Name>Fan</Name>
    </Person>
</Folks>

Tip: If you want to avoid strong constraints when you create linking elements, just use normal attribute types ....

Entities

Entities can be defined as reusable fragments that are either substituted in the DTD or the XML.

General entities

Consider entities as abbreviations for some other content. An entity must be defined in the DTD and its contents are substituted when encountered in the XML file. Then, recall that XML initially only defines 5 entities and that HTML does many more...

  • Use the &lt; &amp; &gt; &aquot; &apos; entities to refer to <, &, > ,", and '

Syntax of an internal entity definition:

<!ENTITY entity_name "content">

Syntax of an external entity definition, i.e. contents are defined in a file:

<!ENTITY entity_name SYSTEM "URI">

Syntax for using an entity in an XML document:

&entity_name;
Illustrations of entity definitions
DTD rule XML example Result
<!ENTITY jt "Joe Test"> <para> &jt; is here<para> <para> Joe Test is here</para>
<!ENTITY space "&#160;"> &space;
<!ENTITY copyright "&#xA9;"> &copyright; D. Schneider © D. Schneider
<!ENTITY explanation SYSTEM "project1a.xml"> <citation> &explanation; </citation> <citation> .... contents of file project1a.xml inserted here ... </citation>

Parameter entities

Most professional DTDs use parameter entities that are used to simplify DTD writing since complex DTDs often use same structures all over. Instead of typing these several times for each element definition, one can use an ENTITY construction like these:

 <!ENTITY  % entity_name "content">
 <!ENTITY  % entity_name SYSTEM "URI">

Example DTD entities defining reusable child elements

 <!ENTITY % Content "(Para | List | Listing)*">

Later in the DTD we then can build element definitions like this:

 <!ELEMENT Intro (Title, %Content; ) >
 <!ELEMENT Goal (Title, %Content; ) >

The XML parser will then simply substitute these %Content; symbols and we get the following "real" DTD rules:

 <!ELEMENT Intro (Title, (Para | List | Listing)*) >
 <!ELEMENT Goal (Title, (Para | List | Listing)* ) >

Example of a DTD entity declaration for a list of common attributes

 <!ENTITY % stamp '
   id ID #IMPLIED
   creation-day NMTOKEN #IMPLIED
   .......
   mod-by NMTOKEN #IMPLIED
   version NMTOKEN #IMPLIED
   status (draft|final|obsolete) #IMPLIED
   approval (ok|not-ok|so-so) #IMPLIED
   main-author CDATA #IMPLIED
   '>

ATTLIST definitions below use %stamp;

 <!ELEMENT main-goal (title, content, (after-thoughts)?, (teacher-comments)?)>
 <!ATTLIST main %stamp; >
 <!ELEMENT title (...)>
 <!ATTLIST main %stamp; >

A complex text-centric example

Use case description

Two DTDs that will help students write research projects and reports. Both include/use a HTML-like DTD to specify formating of element’s contents. Do not worry if you don’t understand all the details, but we believe it’s important to demonstrate in this course some more "real life" examples

We define two DTDs and reuse a third one in both

Each of these DTDs only defines top-level "semantic tags" that define the essential structure of each document type. Elements then contain further markup that is just "stylistic" and taken from the XHTML specification.

In these DTDs we include the ibtwsh6_ePBL DTD as an external entity like this:

<! ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd" >
%foreign-dtd;
For each tag in which we allow stylistic markup, we then can use constructs like:
<!ELEMENT introduction %struct.model;>
<!ELEMENT conclusion %struct.model;>

The Itsy Bitsy Teeny Weeny Simple Hypertext DTD

ibtwsh.dtd is a popular mini XHTML that is used to "fill in" child elements of a semantically structured DTD. Here we present a slightly modified version that we used for DTDs to support project-oriented teaching as shown in the examples further down.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!--
        WARNING: SLIGHTLY MODIFIED FOR USE AT TECFA ! GET THE ORIGINAL
        from http://www.ccil.org/%7Ecowan/XML/ibtwsh6.dtd

	ibtwsh.dtd
	This is the Itsy Bitsy Teeny Weeny Simple Hypertext DTD.
	Its public identifier is -//XML-DEV List//DTD IBTWSH 6.0//EN
	The contents are dedicated to the public domain by
		the author, John Cowan <cowan@ccil.org>, except that
		John Cowan retains the moral right to be known as the author.
	This is draft 6.0
	03/04/2001 Changed by Vivian Synteta 
	Changes: 
	- Correct a mistake (LI)
	- Add IDREF to element "A"
        - Take out id from entity all and IDREFS headers from tables and 
          IDREF from element a 
-->

<!-- 
======================================================================
This is an XML DTD which describes a subset of XHTML Basic for embedded
use within other XML DTDs.  It is by intention equivalent
(within its scope) to -//W3C//DTD XHTML 1.1//EN, but is
not a derived work in the copyright sense.  (Brief excerpts from
HTML 4.0 Transitional appear here and there.)

It is often convenient for XML documents to have a bit of
documentation somewhere in them.  In the absence of a DTD like
this one, that documentation winds up being #PCDATA only, which is
a pity, because rich text adds measurably to the readability of
documents.  By incorporating this DTD by reference (as an
external parameter entity) into another DTD, that DTD inherits
the capabilities of this one.  Using HTML-compatible elements
and attributes allows the documentation to be passed straight
through to HTML renderers.

Current HTML renderers can cope with most XML tags, but empty
tags require special treatment.  Inserting a space before the
terminating "/>" usually makes the "/" (which is not HTML)
invisible.  Using "<tag></tag>" is not as effective, as the
latter is often misinterpreted as a second "<tag>".

Note that since the elements of this DTD are intended to be
used within domain-specific elements of the surrounding DTD,
it is not necessary that every fragment begin with an "html"
element, as in HTML.  Recommended content models for elements
containing documentation are "%horiz.model;" for simple
text fragments and "%struct.model;" for documents in extenso.

Draft 6.0 is seriously incompatible with drafts 5.0 and earlier,
but *is* a subset of XHTML Basic.  I will keep draft 5.0 around;
note that I have changed the FPI.
======================================================================
-->


<!-- =========== Common attributes =========== -->

<!-- All elements (except full-document elements) have these attributes -->
<!ENTITY % all		"id   ID    #IMPLIED
	                ref   IDREF #IMPLIED
		        class CDATA #IMPLIED
			title CDATA #IMPLIED">

<!-- All non-empty elements have these attributes -->
<!ENTITY % i18n		"xml:lang CDATA #IMPLIED
			dir (ltr|rtl) 'ltr'">

<!-- =========== Models =========== -->

<!ENTITY % horiz "#PCDATA | a | abbr | acronym | br | cite | code |
		dfn | em | img | kbd | q | samp | span |
		strong | var">

<!ENTITY % vert "address | blockquote | div | dl | h1 | h2 | h3 |
		ol | p | pre | table | ul">

<!ENTITY % horiz.model "(%horiz;)*">

<!ENTITY % vert.model "(%horiz; | %vert;)*">

<!ENTITY % struct.model "(%vert;)*">


<!-- =========== Horizontal formatting elements =========== -->

<!-- Abbreviations (normal) -->
<!ELEMENT abbr %horiz.model;>
<!ATTLIST abbr %all;>

<!-- Acronyms (normal) -->
<!ELEMENT acronym %horiz.model;>
<!ATTLIST acronym %all;>

<!-- Citation (italics) -->
<!ELEMENT cite %horiz.model;>
<!ATTLIST cite 
	%all;>

<!-- Source code (monowidth) -->
<!ELEMENT code %horiz.model;>
<!ATTLIST code
	%all;>

<!--Terms being defined (normal) -->
<!ELEMENT dfn %horiz.model;>
<!ATTLIST dfn
	%all;>

<!--Emphasis (italics) -->
<!ELEMENT em %horiz.model;>
<!ATTLIST em
	%all;>

<!--Keyboard input -->
<!ELEMENT kbd %horiz.model;>
<!ATTLIST kbd
	%all;>

<!-- Quotation (appropriate quotation marks) -->
<!ELEMENT q %horiz.model;>
<!ATTLIST q
	%all;
	cite CDATA #IMPLIED>

<!-- Sample output text (monowidth) -->
<!ELEMENT samp %horiz.model;>
<!ATTLIST samp
	%all;>

<!-- Arbitrary span of text -->
<!ELEMENT span %horiz.model;>
<!ATTLIST span
	%all;>

<!-- Strong emphasis (boldface) -->
<!ELEMENT strong %horiz.model;>
<!ATTLIST strong
	%all;>

<!-- Variable names (italics) -->
<!ELEMENT var %horiz.model;>
<!ATTLIST var
	%all;>


<!-- IMGs added DKS -->
<!ELEMENT img EMPTY>
<!ATTLIST img
  src     CDATA  #REQUIRED
  alt     CDATA  #IMPLIED
  height  CDATA  #IMPLIED
  width   CDATA  #IMPLIED
  align   CDATA  #IMPLIED
  border  CDATA  #IMPLIED
  hspace  CDATA  #IMPLIED
  vspace  CDATA  #IMPLIED
  %all;>


<!-- Hypertext anchors.
	CONSTRAINT: A elements are not allowed inside
	other A elements, a fact that XML cannot express. -->
<!ELEMENT a %horiz.model;>
<!ATTLIST a
	%all;
	href  CDATA #IMPLIED
	name  CDATA #IMPLIED
	rel   CDATA #IMPLIED
	rev   CDATA #IMPLIED
	target (_BLANK | _TOP | _PARENT) #IMPLIED
>

<!-- Mandatory line breaks -->
<!ELEMENT br EMPTY>
<!ATTLIST br
	%all;>

<!-- =========== Headers =========== -->

<!ELEMENT h1 %horiz.model;>
<!ATTLIST h1
	%all;>

<!ELEMENT h2 %horiz.model;>
<!ATTLIST h2
	%all;>

<!ELEMENT h3 %horiz.model;>
<!ATTLIST h3
	%all;>


<!-- =========== Lists =========== -->

<!-- Definition list -->
<!ELEMENT dl (dt|dd)+>
<!ATTLIST dl
	%all;>

<!-- Defined term -->
<!ELEMENT dt %horiz.model;>
<!ATTLIST dt
	%all;>

<!-- Definition -->
<!ELEMENT dd %horiz.model;>
<!ATTLIST dd
	%all;>

<!-- Ordered list -->
<!ELEMENT ol (li)+>
<!ATTLIST ol
	%all;>

<!-- Unordered list -->
<!ELEMENT ul (li)+>
<!ATTLIST ul
	%all;>

<!-- List element -->
<!ELEMENT li %horiz.model;>
<!ATTLIST li
	%all;>



<!-- =========== Basic table support =========== -->

<!-- Shared attributes -->
<!ENTITY % aligns
	"align (left | center | right | justify) #IMPLIED
	valign (top | middle | bottom | baseline) #IMPLIED">

<!-- Table -->
<!ELEMENT table (caption?, tr+)>
<!ATTLIST table
	%all;
	border      CDATA #IMPLIED
	cellpadding CDATA #IMPLIED
	cellspacing CDATA #IMPLIED
	summary     CDATA #IMPLIED
	width       CDATA #IMPLIED>

<!-- Table caption -->
<!ELEMENT caption %horiz.model;>
<!ATTLIST caption
	%all;>

<!-- Table row -->
<!ELEMENT tr (th | td)+>
<!ATTLIST tr
	%all;
	%aligns;>
	

<!-- Table header -->
<!ELEMENT th %vert.model;>
<!ATTLIST th
	%all;
	%aligns;
	abbr    CDATA #IMPLIED
	axis    CDATA #IMPLIED
	colspan CDATA "1"
	rowspan CDATA "1"
	scope   CDATA #IMPLIED>

<!-- Table data -->
<!ELEMENT td %vert.model;>
<!ATTLIST td
	%all;
	%aligns;
	abbr    CDATA #IMPLIED
	axis    CDATA #IMPLIED
	colspan CDATA "1"
	rowspan CDATA "1"
	scope   CDATA #IMPLIED>


<!-- =========== Other vertical elements =========== -->

<!-- Address block -->
<!ELEMENT address %horiz.model;>
<!ATTLIST address
	%all;>

<!-- Block quotation -->
<!ELEMENT blockquote %struct.model;>
<!ATTLIST blockquote
	%all;
	cite CDATA #IMPLIED>

<!-- General text division -->
<!ELEMENT div %struct.model;>
<!ATTLIST div
	%all;>

<!-- Paragraph -->
<!ELEMENT p %horiz.model;>
<!ATTLIST p
	%all;>

<!-- Preformatted text -->
<!ELEMENT pre %horiz.model;>
<!ATTLIST pre
	%all;>

<!-- =========== END OF ibtwsh.dtd =========== -->

ePBL Project

This DTD allows to define an exploratory student research project and also to keep track of progress by updating certain elements. Other versions were made for projects in experimental psychology.

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!-- ___________________________________________ _____________________  -->
<!-- ePBL-project DTD for student project management & specification    -->
<!--   Copyright: (2004) Paraskevi.Synteta@tecfa.unige.ch 	        -->
<!--              http://tecfa.unige.ch/~paraskev/                      -->
<!--                            Daniel K. Schneider             	-->
<!--              http://tecfa.unige.ch/tecfa-people/schneider.html     -->
<!--   Created: 13/11/2002 (based on EVA_pm grammar)     	        -->
<!--   Updated: 07/05/2004					        -->
<!-- VERSIONS							        -->
<!-- v1.1 Adaptations to use with Morphon xml editor and addition of IDs-->
<!-- v1.1b fixed vert.model to struct.model / DKS 2004                  -->
<!-- _________________________________________________________________  -->

<!-- _______________________ ENTITY DECLARATIONS _____________________  -->

<!ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd">
%foreign-dtd;

<!ENTITY % id  "id  ID    #IMPLIED">

<!--  _______________________ MAIN ELEMENT  _______________________ -->
<!ELEMENT project  (name, authors, date, updated, goal, state-of-the-art,
                    research-development-questions, methodology, workpackages ) >

<!ELEMENT name  (#PCDATA )>

<!ELEMENT date (#PCDATA )>

<!ELEMENT authors (#PCDATA )>

<!ELEMENT updated (#PCDATA )>

<!ELEMENT goal (title, description )>

<!ELEMENT state-of-the-art  %struct.model;>
<!ATTLIST state-of-the-art  %id;>

<!ELEMENT research-development-questions (question )+>
<!ELEMENT question (title, description )>

<!ELEMENT methodology  %struct.model;>
<!ATTLIST methodology  %id;>

<!ELEMENT workpackages (workpackage )+>
<!ELEMENT workpackage (planning, objectives, deliverables )>
<!ATTLIST workpackage  %id;>

<!ELEMENT objectives (objective )+>
<!ELEMENT objective (title, description )>

<!ELEMENT deliverables (deliverable )+>
<!ELEMENT deliverable (url, title, description )>
<!ELEMENT url  (#PCDATA )>

<!ELEMENT planning (from, to, hours-of-work?, progress )>
<!ELEMENT from  (#PCDATA )>
<!ELEMENT to  (#PCDATA )>
<!ELEMENT hours-of-work  (#PCDATA )>
<!ELEMENT progress  (#PCDATA )>
<!-- ____________________________________________________________ -->

<!ELEMENT title  (#PCDATA )>
<!ATTLIST title  %id;>

<!ELEMENT description %struct.model;>
<!-- ____________________________________________________________ -->

ePBL paper

We used several versions of this, depending on the nature of the paper we wanted the students to produce.

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- ___________________________________________ _____________________  -->
<!-- ePBL-paper DTD for student project management & specification      -->
<!--   Copyright: (2004) Paraskevi.Synteta@tecfa.unige.ch 	        -->
<!--              http://tecfa.unige.ch/~paraskev/                      -->
<!--                            Daniel K. Schneider             	-->
<!--              http://tecfa.unige.ch/tecfa-people/schneider.html     -->
<!--   Created: 13/11/2002 (based on EVA_paper grammar)     	        -->
<!--   Updated: 07/05/2004					        -->
<!-- VERSIONS							        -->
<!-- v1.1 Adaptation to use with Morphon xml editor and add IDs, IDREFs -->
<!-- v1.1b fixed vert.model to struct.model / DKS 2004                  -->
<!-- SEE ALSO the book.dtd made by DKS that is simply a superset        -->
<!-- _________________________________________________________________  -->

<!ENTITY % foreign-dtd SYSTEM "ibtwsh6_ePBL.dtd">
<!ENTITY % id  "id  ID    #REQUIRED">

<!-- _________________________ content ________________________________ -->
     
%foreign-dtd;

<!ELEMENT paper ( info, abstract, (preface)?, introduction, main, conclusion, references, (annex)?, (aknowledgements)? ) >

<!ELEMENT info  ( title, authors, date, updated, keywords )>
<!ELEMENT title (#PCDATA )>
<!ELEMENT authors (author )+>
<!ELEMENT author (firstname, familyname, homepageurl, email )>
<!ELEMENT firstname (#PCDATA )>
<!ELEMENT familyname (#PCDATA )>
<!ELEMENT homepageurl (#PCDATA )>
<!ATTLIST homepageurl %all;>
<!ELEMENT email (#PCDATA )>

<!ELEMENT date (#PCDATA )>
<!ELEMENT updated (#PCDATA )>
<!ELEMENT keywords (keyword )+>
<!ELEMENT keyword (#PCDATA )>

<!ELEMENT abstract (#PCDATA )>

<!ELEMENT preface %struct.model;>

<!ELEMENT introduction %struct.model;>

<!ELEMENT main %struct.model;>

<!ELEMENT conclusion %struct.model;>

<!ELEMENT references (reference )+>
<!ELEMENT reference %struct.model;>
<!ATTLIST reference %all;>

<!ELEMENT annex %struct.model;>

<!ELEMENT aknowledgements %struct.model;>

Some advice for designing DTDs

General advice

Don't forget elements and be liberal
  • Each element needs to be defined, but only once !
  • Only make elements mandatory if they really are wanted, i.e. make the others optional, e.g. by using the "?" as in element?
Plan the global structure
  • Before you start writing out DTDs, use some simple "language" to draft the structure, e.g. use a notation like:
name   ==>  family given
family ==> "text"
  • In most cases, each "object" of your "information domain" becomes an element
  • Use child elements to model components
  • Use attributes to describe properties of components
Start from the root element and work your way down
  1. Root element
  2. Child elements of root element
  3. Child elements of the other elements, etc.

Attributes vs. Elements

  • There are some design rules that may help you decide whether using an element or an attribute
  • In case of doubt, always use elements ...
Rather use child elements inside an element to represent an information block
  • if order is important (attributes can't be ordered)
  • if you plan to use the same kind of information block with different parents
  • if a future version of DTD may specify sub-components of an information block
  • if the information block represents a "thing" (an object in OO programming)
  • if the DTD is text-centric, because an author must see contents she/he edits and attributes are often hidden away in XML editors; only use attributes to qualify properties like style !
Rather use attributes to represent an information block
  • if an attribute refers to an other element:
<pet_of owner_name="lisa" pet_type="cat"> would refer to <animal category="cat">
  • to declare usage/type/etc. of an element:
 <address usage="prof"> ... </address>
  • if you wish to list all possible values a user can enter
  • if you want to restrict data type of the attribute value (e.g. require a single word)