Mark Johnson
An XML general entity (covered in a previous newsletter) defines a
symbolic name for text used in multiple places in an instance document.
When the document is processed, the text it refers to replaces the
entity. For example, the general character entity expands to a
non-breaking space (meaning a line break can't occur to the immediate
left or right of the space). So, general entities let you create
symbolic names for chunks of text, which you can then refer to in
instance documents. But what about doing the same thing in a DTD? How
do you define a piece of a model group for reuse in multiple places in
a grammar?
The answer to this question is the "parameter entity". Parameter
entities are symbolic names that evaluate to a particular chunk of
text, just like general entites. But parameter entities can be used in
DTDs, whereas general entities cannot. Basically, parameter entities
let you reuse parts of a DTD.
The easiest way to show how to use a parameter entity in a DTD is by
example. Let's say you're creating a DTD to represent the results of a
typical questionnaire and you want to use the same model group over and
over for the result set. (Please ignore that the information in this
example is very poorly modeled -- the parameter entity mechanism is the
point.) The result set from a single customer response might look
something like this:
<CustomerSatisfaction>
<Id>
<Customer>12</Customer>
<Date>2001-01-05</Date>
</Id>
<Responses>
<Q1><Cool/></Q1>
<Q2><Awesome/></Q2>
<Q3><Bites/></Q3>
<Q4><NoAnswer/></Q4>
</Responses>
</CustomerSatisfaction>
Here's the DTD for this instance document:
<!DOCTYPE CustomerSatisfaction [
<!ELEMENT CustomerSatisfaction (Id, Responses)>
<!ELEMENT Id (Customer, Date)>
<!ELEMENT Customer (#PCDATA)>
<!ELEMENT Date (#PCDATA)>
<!ELEMENT Responses (Q1,Q2,Q3,Q4)>
<!ELEMENT Q1 (Cool|Awesome|Blah|Bites|NoAnswer)>
<!ELEMENT Q2 (Cool|Awesome|Blah|Bites|NoAnswer)>
<!ELEMENT Q3 (Cool|Awesome|Blah|Bites|NoAnswer)>
<!ELEMENT Q4 (Cool|Awesome|Blah|Bites|NoAnswer)>
<!ELEMENT Cool EMPTY>
<!ELEMENT Awesome EMPTY>
<!ELEMENT Blah EMPTY>
<!ELEMENT Bites EMPTY>
<!ELEMENT NoAnswer EMPTY>
]>
Notice that the options for the answers responses to Q1-Q4 are used
over and over again. You could simplify this DTD with a parameter
entity, like so:
<!ELEMENT CustomerSatisfaction (Id, Responses)>
<!ELEMENT Id (Customer, Date)>
<!ELEMENT Customer (#PCDATA)>
<!ELEMENT Date (#PCDATA)>
<!ELEMENT Responses (Q1,Q2,Q3,Q4)>
<!ENTITY % Choices "Cool|Awesome|Blah|Bites|NoAnswer">
<!ELEMENT Q1 (%Choices;)>
<!ELEMENT Q2 (%Choices;)>
<!ELEMENT Q3 (%Choices;)>
<!ELEMENT Q4 (%Choices;)>
<!ELEMENT Cool EMPTY>
<!ELEMENT Awesome EMPTY>
<!ELEMENT Blah EMPTY>
<!ELEMENT Bites EMPTY>
<!ELEMENT NoAnswer EMPTY>
Using parameter entities in this way simplifies the maintenance of sub-
pieces of model groups that are used in multiple places of a DTD. Now
that you understand the basics, upcoming newsletters will explain other
uses of parameter entities.