| Previous | Next
Parameter EntitiesIt is not uncommon for multiple elements to share all or part of the same attribute lists and content specifications. For instance, any element that's a simple XLink will have For example, consider an XML application for residential real-estate listings that provides separate elements for apartments, sublets, coops for sale, condos for sale, and houses for sale. The element declarations might look like this: <!ELEMENT apartment (address, footage, rooms, baths, rent)> <!ELEMENT sublet (address, footage, rooms, baths, rent)> <!ELEMENT coop (address, footage, rooms, baths, price)> <!ELEMENT condo (address, footage, rooms, baths, price)> <!ELEMENT house (address, footage, rooms, baths, price)> There's a lot of overlap between the declarations, i.e., a lot of repeated text. And if you later decide you need to add an additional element, An entity reference is the obvious candidate here. However, general entity references are not allowed to provide replacement text for a content specification or attribute list, only for parts of the DTD that will be included in the XML document itself. Instead, XML provides a new construct exclusively for use inside DTDs, the parameter entity, which is referred to by a parameter entity reference. Parameter entities behave like and are declared almost exactly like a general entity. However, they use a Parameter Entity SyntaxA parameter entity reference is declared much like a general entity reference. However, an extra percent sign is placed between the <!ENTITY % residential_content "address, footage, rooms, baths"> <!ENTITY % rental_content "rent"> <!ENTITY % purchase_content "price"> Parameter entities are dereferenced in the same way as a general entity reference, only with a percent sign instead of an ampersand: <!ELEMENT apartment (%residential_content;, %rental_content;)> <!ELEMENT sublet (%residential_content;, %rental_content;)> <!ELEMENT coop (%residential_content;, %purchase_content;)> <!ELEMENT condo (%residential_content;, %purchase_content;)> <!ELEMENT house (%residential_content;, %purchase_content;)> When the parser reads these declarations, it substitutes the entity's replacement text for the entity reference. Now all you have to do to add an <!ENTITY % residential_content "address, footage, rooms, baths, available_date"> The same technique works equally well for attribute types and element names. You'll see several examples of this in the next chapter on namespaces and in . This trick is limited to external DTDs. Internal DTD subsets do not allow parameter entity references to be only part of a markup declaration. However, parameter entity references can be used in internal DTD subsets to insert one or more entire markup declarations, typically through external parameter entities. Redefining Parameter EntitiesWhat makes parameter entity references particularly powerful is that they can be redefined. If a document uses both internal and external DTD subsets, then the internal DTD subset can specify new replacement text for the entities. If <!ENTITY % residential_content "address, footage, rooms, bedrooms, baths, available_date"> In the event of conflicting entity declarations, the first one encountered takes precedence. The parser reads the internal DTD subset first. Thus the internal definition of the Modular XHTML, which we'll discuss in , makes heavy use of this technique to allow particular documents to select only the subset of HTML that they actually need. External DTD SubsetsReal-world DTDs can be quite complex. The SVG DTD is over 1,000 lines long. The XHTML 1.0 strict DTD (the smallest of the three XHTML DTDs) is more than 1,500 lines long. And these are only medium-sized DTDs. The DocTutorial XML DTD is over 11,000 lines long. It can be hard to work with, comprehend, and modify such a large DTD when it's stored in a single monolithic file. Fortunately, DTDs can be broken up into independent pieces. For instance, the DocTutorial DTD is distributed in 28 separate pieces covering different parts of the spec: one for tables, one for notations, one for entity declarations, and so on. These different pieces are then combined at validation time using external parameter entity references. An external parameter entity is declared using a normal <!ENTITY % names SYSTEM "names.dtd"> %names; You can use either relative or absolute URIs as convenient. In most situations, relative URIs are more practical. |