Possible Problems with Parameter Entities

The parameter entities have made the overall DTD more compact, but have they made it more readable? In general, grouping items into parameter entities can make the document more readable, but keep in mind that if you go too far and create too many parameter entities, it might be nearly impossible for a human to read your DTD. For example, most developers would consider the basic form objects (button, label, textArea, and so on) to be the primary child elements of a form element. However, you will need to dig through many layers of the XHTML DTD to discover that these elements are actually child elements of the form element.

In the XHTML DTD, the form objects are defined in an internal parameter entity named inline.forms, which is included in the inline parameter entity. The inline entity is used in the Inline parameter entity, which in turn is used in the p element's declaration. The p element is included in the block parameter entity's declaration, and the block entity is included in the form.content parameter entity. Finally, the form.content entity is included in the form element's declaration, as shown here:

  <!ENTITY % inline.forms "input | select | textarea | label
      | button">
  <!ENTITY % inline
            "a | %special; | %fontstyle; | %phrase; | %inline.forms;">
  <!ENTITY % Inline "(%inline;| %misc;)*">
  <!ELEMENT p %Inline;>
  <!ENTITY % block
      "p | %heading; | div | %lists; | %blocktext; | fieldset |
  <!ENTITY % form.content "(%block; | % inline; | %misc;)*">
  <!ELEMENT form %form.content;>

To use a form object such as select, you will need to include the following statement in your XML document:


There is another path to the form objects. Notice that the block entity declaration includes a fieldset element. The fieldset element also contains the inline element, just as the p element did, as shown here:

  <!ENTITY % inline.forms "input | select | textarea | label |
  <!ENTITY % inline
      "a | %special; | %fontstyle; | %phrase; |
  <!ELEMENT fieldset (#PCDATA | legend | %block; | form |
      %inline; | %misc;)*>
  <!ENTITY % block
      "p | %heading; | div | %lists; | %blocktext; | fieldset |
  <!ENTITY % form.content "(%block; | %misc;)*">
  <!ELEMENT form %form.content;>

To use a form object such as select in this case, you would include the following statement in your XML document:


You can use an XML tool to view this relationship. An excellent tool for viewing the structure of an XML DTD is Near and Far, available at http://www.microstar.com. Without an XML tool, the parameter entities make the DTD nearly impossible to read. Try to strike a balance by using enough parameter entities to create reusable groups that make your DTD neater but not so many parameter entities that your DTD is unreadable.

You must also be careful that the document is still valid and well formed once the parameter entity has been substituted. For example, consider the following declaration:

  <!ENTITY % Inline " (#PCDATA
                     | %inline;
                     | %misc;)*">

As you can see, this declaration is missing the closing parenthesis. When the Inline parameter entity is substituted, it will create an invalid declaration. Be sure that all your components are properly nested, opened, and closed after the entities are substituted.

A common problem when working with XML is finding errors in your XML documents and your DTDs. Often XML tools display cryptic error messages that leave you with no idea as to the real source of a problem. XML Notepad, can be used for writing and debugging XML documents that have no external DTDs. XML Authority works well with DTDs and usually provides clear error messages that help you locate errors in your DTD. If you are working with an XML document that references an external DTD, Web Writer usually provides helpful error messages. All of these products provide trial versions. Try them all, and then choose the tools that best meet your needs. Be aware that sometimes a small error in a DTD could take a long time to track down (for example, using Block instead of block in the preceding DTD will cause an error that might take several hours to track down).