A DTD Example

Because being able to create DTDs is an essential XML skill these days (at least until XML schemas are widely supported), I'll work through another example here.

This new example is a model for a book, complete with <CHAPTER> , <SECTION> , <PART> , and <SUBTITLE> elements. Here's what the document will look like:

Listing ch03_08.xml
 <?xml version="1.0"?> <!DOCTYPE BOOK [     <!ELEMENT p (#PCDATA)>     <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)>     <!ELEMENT OPENER       (TITLE_TEXT)*>     <!ELEMENT TITLE_TEXT   (#PCDATA)>     <!ELEMENT SUBTITLE     (#PCDATA)>     <!ELEMENT INTRODUCTION (HEADER, p+)+>     <!ELEMENT PART         (HEADER, CHAPTER+)>     <!ELEMENT SECTION      (HEADER, p+)>     <!ELEMENT HEADER       (#PCDATA)>     <!ELEMENT CHAPTER      (CHAPTER_NUMBER, CHAPTER_TEXT)>     <!ELEMENT CHAPTER_NUMBER (#PCDATA)>     <!ELEMENT CHAPTER_TEXT (p)+> ]> <BOOK>     <OPENER>         <TITLE_TEXT>             All About Me         </TITLE_TEXT>     </OPENER>     <PART>         <HEADER>Welcome To My Book</HEADER>         <CHAPTER>             <CHAPTER_NUMBER>CHAPTER 1</CHAPTER_NUMBER>             <CHAPTER_TEXT>                 <p>Glad you want to hear about me.</p>                 <p>There's so much to say!</p>                 <p>Where should we start?</p>                 <p>How about more about me?</p>             </CHAPTER_TEXT>         </CHAPTER>     </PART> </BOOK> 

In this case, I'll start the DTD by declaring the <p> element, which I want to hold text onlythat is, PCDATA , which you specify with #PCDATA :

 <!ELEMENT p            (#PCDATA)>           .          .          . 

Next, I'll declare the <BOOK> element, which is the root element. In this case, the <BOOK> element can contain an <OPENER> element, possibly a <SUBTITLE> element, possibly an <INTRODUCTION> element, and one or more sections or parts declared with the <SECTION> and <PART> elements:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)>  .          .          . 

Now I will declare an <OPENER> element. This element will hold the title text for the chapter, which I'll store in <TITLE_TEXT> elements:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)>  <!ELEMENT OPENER       (TITLE_TEXT)*>  .          .          . 

I'll declare the <TITLE_TEXT> element so that it can contain plain text:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*>  <!ELEMENT TITLE_TEXT   (#PCDATA)>  .          .          . 

And I'll declare the <SUBTITLE> element, which must also contain PCDATA :

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*> <!ELEMENT TITLE_TEXT   (#PCDATA)>  <!ELEMENT SUBTITLE     (#PCDATA)>  .          .          . 

I'll set up the <INTRODUCTION> element up so that it can contain a <HEADER> element and must contain one or more <p> elements. I'll allow that sequence to repeat, like this:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*> <!ELEMENT TITLE_TEXT   (#PCDATA)> <!ELEMENT SUBTITLE     (#PCDATA)>  <!ELEMENT INTRODUCTION (HEADER, p+)+>  .          .          . 

Next, the <PART> element can contain a <HEADER> and one or more <CHAPTER> elements:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*> <!ELEMENT TITLE_TEXT   (#PCDATA)> <!ELEMENT SUBTITLE     (#PCDATA)> <!ELEMENT INTRODUCTION (HEADER, p+)+>  <!ELEMENT PART         (HEADER, CHAPTER+)>  .          .          . 

In addition, I'll specify that the <CHAPTER> element must contain a <CHAPTER_NUMBER> and <CHAPTER_TEXT> element:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*> <!ELEMENT TITLE_TEXT   (#PCDATA)> <!ELEMENT SUBTITLE     (#PCDATA)> <!ELEMENT INTRODUCTION (HEADER, p+)+> <!ELEMENT PART         (HEADER, CHAPTER+)> <!ELEMENT SECTION      (HEADER, p+)> <!ELEMENT HEADER       (#PCDATA)>  <!ELEMENT CHAPTER  (CHAPTER_NUMBER, CHAPTER_TEXT)>  .          .          . 

The <CHAPTER_NUMBER> element contains parsed character data:

 <!ELEMENT p            (#PCDATA)>  <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)> <!ELEMENT OPENER       (TITLE_TEXT)*> <!ELEMENT TITLE_TEXT   (#PCDATA)> <!ELEMENT SUBTITLE     (#PCDATA)> <!ELEMENT INTRODUCTION (HEADER, p+)+> <!ELEMENT PART         (HEADER, CHAPTER+)> <!ELEMENT SECTION      (HEADER, p+)> <!ELEMENT HEADER       (#PCDATA)> <!ELEMENT CHAPTER  (CHAPTER_NUMBER, CHAPTER_TEXT)>  <!ELEMENT CHAPTER_NUMBER (#PCDATA)>  .          .          . 

Finally, the <CHAPTER_TEXT> element can contain <p> paragraph elements:

 <!ELEMENT p (#PCDATA)>      <!ELEMENT BOOK         (OPENER,SUBTITLE?,INTRODUCTION?,(SECTION  PART)+)>     <!ELEMENT OPENER       (TITLE_TEXT)*>     <!ELEMENT TITLE_TEXT   (#PCDATA)>     <!ELEMENT SUBTITLE     (#PCDATA)>     <!ELEMENT INTRODUCTION (HEADER, p+)+>     <!ELEMENT PART         (HEADER, CHAPTER+)>     <!ELEMENT SECTION      (HEADER, p+)>     <!ELEMENT HEADER       (#PCDATA)>     <!ELEMENT CHAPTER      (CHAPTER_NUMBER, CHAPTER_TEXT)>     <!ELEMENT CHAPTER_NUMBER (#PCDATA)>  <!ELEMENT CHAPTER_TEXT (p)+>  

And that's it; the DTD is finished.



Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net