Is there a way to extend a DTD used for validation?

526 Views Asked by At

I am wondering whether there is a standard way to extend a DTD or whether the only way to validate a document is to add all the necessary extensions in the XML file.

I have a system of plugins that are generally organized like packages in a Linux installation (i.e. plugins can depend on one or more plugins, loops are not allowed):

             +----------------------+
         +-->|  Editor              |<--+
         |   +----------------------+   |
         |                              |
+-----------------+            +-----------------+
|  Locale         |            | Image           |
+-----------------+            +-----------------+
         ^                              ^
         |                              |
         |   +----------------------+   |
         +---|  GeoMap              |---+
             +----------------------+

So, what I have is a DTD in the Editor plugin with, for example, a widget tag that has an attribute named auto-save like this:

<!ELEMENT widget (value|preset|default|state)*>
<!ATTLIST widget id ID #REQUIRED
                 type NMTOKEN #REQUIRED
                 auto-save (double | html | int8 
                           | date-us | no | string) "string">

The fact is that when I add the locale, I now want the auto-save attribute to also support a type such as locale-date which is not specific to the US.

Similarly, the Image plugin may want to add an image type and the GeoMap plugin could use geo-location.

So in the end, the ATTLIST auto-save should look like this (obviously, the order does not matter):

auto-save (double | html | int8 | date-us | no 
          | string | locale-date | image | geo-location) "string"

Even when defining multiple DTDs in an XML file (xmlns=... attributes in the root tag), I do not think you can do that, can we?

Right now I can add the types in the editor.dtd, but that's obviously wrong to define the locale, image, and geomap types when those plugins may not be available in your graph...

The one other solution I can think of would be to use XSD, but even with that format, how do I go by to add sub-additions of attributes and tags?

2

There are 2 best solutions below

2
On

I don't think you can create a DtD as an extension of another.

Best alternative is probably parameter entities, which can be used to extend the DtD when importing it in XML. The W3C have some general examples of their use for modulization of DtD's.

In your case, the widget declaration can be changed to [widget.dtd]:

<!ELEMENT widget (value|preset|default|state)*>
<!ENTITY % AUTO-SAVE-ENUMS-EXTRA "">      <!-- additional auto-save values -->
<!ATTLIST widget id ID #REQUIRED
                 type NMTOKEN #REQUIRED
                 auto-save (double | html | int8 
                           | date-us | no | string %AUTO-SAVE-ENUMS-EXTRA;) "string" >

This has introduced the %AUTO-SAVE-ENUMS-EXTRA; parameter entity with the default value "" (empty string). This can be overidden to extend the enumeration list when the DtD is imported:

<!DOCTYPE widget SYSTEM "widget.dtd" [
    <!ENTITY % AUTO-SAVE-ENUMS-EXTRA "| locale-date | image | geo-location">
]>
<widget id="foo" type="test" auto-save="geo-location"/>

With regard to how to more generally edit the attributes and entities in a DtD. Adding attributes and entities is straight-forward. However inserting new entities into an existing document tree normally involves parameter entities.

Consider Document.dtd:

<!ENTITY % Document-Elements-Extra "">
<!ELEMENT Document (P|H1|H2 %Document-Elements-Extra;)*>
<!ELEMENT P (#PCDATA)>
<!ELEMENT H1 (#PCDATA)>
<!ELEMENT H2 (#PCDATA)>

The following XML file imports the DtD, adding the H3 Element and also adding a type attribute to the P element:

<!DOCTYPE Document SYSTEM "Document.dtd" [
    <!ATTLIST P type CDATA #IMPLIED>
    <!ELEMENT H3 (#PCDATA)>
    <!ENTITY % Document-Elements-Extra "|H3">
]>
<Document>
  <H1>Level 1 Header</H1>
  <P type="test">This is a test of DtD parameter entities</P>
  <H3>Level 3 Header</H3>
</Document>
0
On

DTDs are not extensible. But at the same time, XML schemas can be used which are extensible.