The element tasklist may contain at most one title and at most one description, additionally any number (incl. 0) task elements in any order.
The naive approach is not applicable, since the order should not matter:
<!ELEMENT tasklist (title?, description?, task*) >
Alternatively, I could explicitly name all possible options:
(title, description?, task*) |
(title, task+, description?, task*) |
(task+, title, task*, description?, task*) |
(description, title?, task*) |
(description, task+, title?, task*) |
(task+, description, task*, title?, task*) |
(task*)
but then it’s quite easy to write a non-deterministic rule, and furthermore it looks like the direct path to darkest madness. Any ideas, how this could be done more elegantly?
And no, an XSD or RelaxNG is no option. I need a plain, old DTD.
This summarises what you need:
Alternation for the
titleappearing before/afterdescription.However, this is not a deterministic content model, as @13ren explains in his answer. [Here is another example from Microsoft](http://msdn.microsoft.com/en-us/library/9bf3997x(VS.71).aspx).
In short
Your requirements is to have a non-deterministic model, and as such, there is no possible valid DTD for your scenario.
Alternatives
If you place a simple restriction that either
taskordescriptionmust be the last element if bothtaskanddescriptionare provided, you can use this deterministic DTD declaration:Examples:
Or, possibly more naturally, enforce that a
titleordescriptionelement must be the first element, and bothtitleanddescriptionelements must exist or be non-existent.Examples:
Otherwise
Otherwise, you need to use RELAX NG, which allows for non-deterministic models.