After full parameterization, the entire DTD resembles the listing below. <!ENTITY % statement.prefix "stmt"> <!ENTITY % statement.colon ":"> <!ENTITY % NamespaceDeclaration "xmlns%statement.colon;%statement.prefix;"> <!ENTITY % Statement.qname "%statement.prefix;%statement.colon;Statement"> <!ENTITY % Bank.qname "%statement.prefix;%statement.colon;Bank"> <!ENTITY % Date.qname "%statement.prefix;%statement.colon;Date"> <!ENTITY % Transaction.qname "%statement.prefix;%statement.colon;Transaction"> <!ENTITY % Amount.qname "%statement.prefix;%statement.colon;Amount"> <!ENTITY % Account.qname "%statement.prefix;%statement.colon;Account"> <!ENTITY % Number.qname "%statement.prefix;%statement.colon;Number"> <!ENTITY % Owner.qname "%statement.prefix;%statement.colon;Owner"> <!ENTITY % Type.qname "%statement.prefix;%statement.colon;Type"> <!ENTITY % OpeningBalance.qname "%statement.prefix;%statement.colon;OpeningBalance"> <!ENTITY % ClosingBalance.qname "%statement.prefix;%statement.colon;ClosingBalance"> <!ATTLIST %Statement.qname; %NamespaceDeclaration; CDATA #FIXED "http://namespaces.megabank.com/"> <!ELEMENT %Statement.qname; ( %Bank.qname;, %Account.qname;, %Date.qname;, %OpeningBalance.qname;, (%Transaction.qname;)*, %ClosingBalance.qname;) > <!ELEMENT Account (%Number.qname;, %Type.qname;, %Owner.qname;)> <!ELEMENT %Number.qname; (#PCDATA)> <!ELEMENT %Type.qname; (#PCDATA)> <!ELEMENT %Owner.qname; (#PCDATA)> <!ELEMENT %OpeningBalance.qname; (#PCDATA)> <!ELEMENT %ClosingBalance.qname; (#PCDATA)> <!ELEMENT %Bank.qname; (#PCDATA)> <!ELEMENT %Date.qname; (#PCDATA)> <!ELEMENT %Amount.qname; (#PCDATA)> <!ENTITY % TransactionContent "%Account.qname;?, %Date.qname;, %Amount.qname;"> <!ELEMENT %Transaction.qname; ( %TransactionContent; )> <!ENTITY % TypeAtt "type"> <!ENTITY % type.extra ""> <!ATTLIST %Transaction.qname; %TypeAtt; (withdrawal deposit transfer %type.extra; ) #REQUIRED The downside is that this DTD is a lot less legible than the unparame-terized DTD. However, the fully parameterized DTD is also much more extensible. There are limits to all this. Sometimes you don't want to allow a DTD to be easily customized, or you want to allow it to be customized in some ways but not in othersfor example, allowing elements to be added but not removed or reordered but not renamed . Generally, this is possible using the right combination of parameter entity references. I've perhaps overparameterized here to make a point, but you're free to pick and choose only those pieces that are helpful in your systems. |