Figure 4   DTD Keywords

Keyword Description
!ELEMENT
tag
(tag1, tag2, …, tagn)
Defines a tag of the language. All the tags that appear between parentheses are its children. For HTML <TABLE> it would be:
 <!ELEMENT table (thead, tr, td)>
Each tag name can have suffixes with special meanings: + implies that the tag can be repeated; * implies that the tag can appear zero or more times; ? implies that the tag is optional.
!ATTLIST
tag
attribute1 type #value
• • •
attributen type #value
Defines the attributes list for the specified tag. An attribute can contain any value or a precise item from a list. In the former case, it is of type CDATA (character data):
 <!ATTLIST table 
           style CDATA #IMPLIED>
Otherwise it's an item of a collection:
 <!ATTLIST CHANNEL PRECACHE (YES | NO) "YES">
PRECACHE can be YES or NO and is YES by default. You can specify also that the value is what's in the file (IMPLIED). An attribute can be also REQUIRED.
!ENTITY % name "value"
This is an XML macro that defines a shortcut for a name or an expression.
 <!ENTITY % Answer "yes | no">
 <!ENTITY Aut "Autobiography">
When using an entity you must use the following notation:
 &Answer; 
The % symbol is required for collection of values.


Figure 6   msmag.dtd


 <!-- Document Type Definition for a Magazine Language -->
 
 <!ENTITY MSJ    "Microsoft Systems Journal">
 <!ENTITY MIND   "Microsoft Internet Developer">
 <!ENTITY MIND_D "The Microsoft Magazine for Web Developers">
 <!ENTITY MFI    "Miller Freeman">
 
 <!ENTITY % Binary  "yes | no">
 
 <!ELEMENT MSMAG (EDITORIAL, COVER*, ARTICLES, COMMENTS?)>
 <!ATTLIST MSMAG name        CDATA #REQUIRED
                 publisher   CDATA #REQUIRED
                 description CDATA #IMPLIED>
  
 <!ELEMENT EDITORIAL (#PCDATA)>               
 <!ATTLIST EDITORIAL volume    CDATA #IMPLIED 
                     number    CDATA #IMPLIED 
                     month     CDATA #IMPLIED
                     year      CDATA "1999"  
                     published (%Binary;) #IMPLIED>
 
 <!ELEMENT COVER (#PCDATA)>
 <!ATTLIST COVER title    CDATA #REQUIRED
                 subtitle CDATA #REQUIRED>
 
 <!ELEMENT ARTICLES (FEATURE+, COLUMN+)>
 
 <!ELEMENT FEATURE (#PCDATA)>
 <!ATTLIST FEATURE author CDATA #REQUIRED>
 
 <!ELEMENT COLUMN (#PCDATA)>
 <!ATTLIST COLUMN name   CDATA #REQUIRED
                  author CDATA #REQUIRED>
 
 <!ELEMENT COMMENTS (#PCDATA)>

Figure 8 CDATA Values

Keyword Description
#IMPLIED The attribute is assigned the value specified in the XML source document. The attribute is optional.
#REQUIRED The attribute must be specified and takes the values specified in the XML source document.
#FIXED "value"
The attribute is always assigned the specified value—no matter what the XML source document specifies.
"value"
The attribute defaults to the specified value unless it is explicitly assigned a value in the XML source document. If the attribute is specified then it retains that value, otherwise it is assigned this one.


Figure 9   An MSMAG Document


 <?xml version="1.0"?>
 <!DOCTYPE MSMAG SYSTEM "MsMag.dtd">
 
 <MSMAG name="&MIND;" publisher="&MFI;" description="&MIND_D;">
 <EDITORIAL volume="4" number="3" month="March" />
 
 <COVER
    title="Windows 2000" 
    subtitle="What Every Web Developer Needs to Know">
 </COVER>
 
 <ARTICLES>
 <FEATURE author="D. Esposito">
 Windows 2000 for Web Developers</FEATURE> 
 <FEATURE author="B. Shankle">
 Find Recombinant Success with Windows DNA</FEATURE > 
 <FEATURE author="M. Tabini">
 Using Stored Procedures in SQL Server</FEATURE> 
 <FEATURE author="C. Nolan">
 Put Advanced SQL Server Features to Work</FEATURE> 
 
 <COLUMN name="Flux" author="D. Boling">
 Pentium III</COLUMN> 
 <COLUMN name="New Stuff" author="T. Carey">
 </COLUMN> 
 <COLUMN name="Geektogeek" author="R. Hess">
 </COLUMN> 
 <COLUMN name="Beyond the Browser" author="K. Spencer">
 Visual InterDev 6.0 Form Manager</COLUMN> 
 <COLUMN name="FAQ" author="K. Kotipalli">
 Namespace Extension AppWizard</COLUMN> 
 <COLUMN name="Extreme C++" author="S. Zimmerman">
 Scalability, State and MTS</COLUMN> 
 </ARTICLES>
 
 </MSMAG>

Figure 11   JScript for Rendering XML


 <HTML>
 
 <HEAD>
 <LINK REL="stylesheet" TYPE="text/css" HREF="msmag.css">
 </HEAD>
 
 <SCRIPT>
 function init() {
   xml = new ActiveXObject("Microsoft.XMLDOM");
   xml.load("mind0399.xml");
 
   // Get the MSMAG object
   msmag = xml.documentElement;
   Desc.innerHTML = msmag.getAttribute("description");
   Publ.innerHTML = msmag.getAttribute("publisher");
   Magz.innerHTML = msmag.getAttribute("name");
   
   // Get the EDITORIAL object
   editorial = xml.getElementsByTagName("EDITORIAL").item(0);
   Vol.innerHTML = editorial.getAttribute("volume");
   Num.innerHTML = editorial.getAttribute("number");
   Issue.innerHTML = editorial.getAttribute("month") + " " + editorial.getAttribute("year");
    
   // Get the COVER object
   coverColl = xml.getElementsByTagName("COVER");
   if (coverColl.length > 0) {
     cover = coverColl.item(0);
     IssueTitle.innerHTML = cover.getAttribute("title");
     IssueSubTitle.innerHTML = cover.getAttribute("subtitle");
   }
   else {
     IssueTitle.innerHTML = "<I>[No Cover Info Provided]</I>";
     IssueSubTitle.innerHTML = "<I>[No Cover Info Provided]</I>";
   }
 
   // Get the ARTICLES object
   articles = xml.getElementsByTagName("ARTICLES").item(0);
   features = articles.getElementsByTagName("FEATURE");
   columns  = articles.getElementsByTagName("COLUMN");
 
   // Enumerates Feature articles
   str = "";
   for(i=0; i<features.length; i++) {
     f = features.item(i);
     if(str != "")
       str += "<HR>";
 
     str += f.getAttribute("author") + ", ";
     str += "<I>" + f.text + "</I>";
   }
   ArtFeatures.innerHTML = str;  
 
   // Enumerates Column articles
   str = "";
   for(i=0; i<columns.length; i++) {
     c = columns.item(i);
     if(str != "")
       str += "<HR>";
 
     str += "<B>" + c.getAttribute("name") + "</B>- ";
     str += c.getAttribute("author") + ", ";
     str += "<I>" + c.text + "</I>";
   }
   ArtColumns.innerHTML = str;  
 }
 </SCRIPT>
 
 
 <BODY onload="init()">
 
 <TABLE width=100%>
 <TR>
 <TD class=EditVolume>Volume <SPAN ID=Vol></TD>
 <TD class=EditVolume>Number <SPAN ID=Num></TD>
 <TD class=EditIssue ID=Issue></TD>
 </TR>
 </TABLE>
 
 <HR>
 
 <TABLE width=100%>
 <TD class=Desc ID=Desc></TD>
 <TD class=Publ ID=Publ></TD>
 </TABLE>
 
 <HR>
 
 <TABLE width=100%>
 <TR><TD class=Magz ID=Magz></TD></TR>
 <TR><TD class=IssueTitle ID=IssueTitle></TD></TR>
 <TR><TD class=IssueSubTitle ID=IssueSubTitle></TD></TR>
 </TABLE>
 
 <TABLE width=100%>
 <TR>
 
 <TD valign=top>
 <TABLE bgcolor=lightyellow width=100% border=1 width=50%>
 <TR><TH class=ColTitle>Features</TH></TR>
 <TD class=StdText ID=ArtFeatures>Features</TD>
 </TABLE>
 </TD>
 
 <TD valign=top>
 <TABLE bgcolor=lightgrey width=100% border=1 width=50%>
 <TR><TH class=ColTitle>Columns</TH></TR>
 <TD class=StdText ID=ArtColumns>Columns</TD>
 </TABLE>
 </TD>
 
 </TR>
 </TABLE>
 
 </BODY>
 </HTML>

Figure 12   MSMAG Data Schema


 <?xml version="1.0"?>
 <Schema name="MSMAG" 
         xmlns="urn:schemas-microsoft-com:xml-data"
         xmlns:dt="urn:schemas-microsoft-com:datatypes">
 <!-- Attribute Types -->
 <AttributeType name="volume" dt:type="string" />
 <AttributeType name="number" dt:type="string" />
 <AttributeType name="month" dt:type="string" />
 <AttributeType name="year" dt:type="string" />
 <AttributeType name="published" dt:type="enumeration" dt:values="yes no"/>
 <AttributeType name="title" dt:type="string" />
 <AttributeType name="subtitle" dt:type="string" />
 <AttributeType name="author" dt:type="string" />
 <AttributeType name="name" dt:type="string" />
 <AttributeType name="description" dt:type="string" />
 <AttributeType name="publisher" dt:type="string" />
 
 <!-- Element Types -->
 <ElementType name="MSMAG" content="eltOnly" model="closed" order="seq">
    <element type="EDITORIAL" minOccurs="1" maxOccurs="1" />   
    <element type="COVER" minOccurs="0" maxOccurs="1" />   
    <element type="ARTICLES" minOccurs="1" maxOccurs="*" />   
    <element type="COMMENTS" minOccurs="0" maxOccurs="1" />   
    <attribute type="name" required="yes" />   
    <attribute type="publisher" required="yes" />   
    <attribute type="description" required="no" 
               default="The Magazine for the Web Developer" /></ElementType>
 <ElementType name="EDITORIAL" content="empty">
    <attribute type="volume"    required="no" />
    <attribute type="number"    required="no" />
    <attribute type="month"     required="no" />
    <attribute type="year"      default="1999" required="no" />
    <attribute type="published" required="no" /></ElementType>
 <ElementType name="COVER" content="empty">
    <attribute type="title"    required="yes" />
    <attribute type="subtitle" required="yes" /></ElementType>
 <ElementType name="COMMENTS" content="textOnly" dt:type="string"></ElementType>
 <ElementType name="FEATURE" content="mixed">
    <attribute type="author"  required="yes" /></ElementType>
 <ElementType name="COLUMN" content="mixed">
    <attribute type="name"  required="yes" />
    <attribute type="author"  required="yes" /></ElementType>
 <ElementType name="ARTICLES" content="eltOnly" model="closed">
    <element type="FEATURE" minOccurs="1" maxOccurs="*" />   
    <element type="COLUMN" minOccurs="1" maxOccurs="*" /></ElementType>
 </Schema>