Pergunta

O elemento tasklist pode conter no máximo um title E no máximo um description, além de qualquer número (incl. 0) task elementos em qualquer ordem.

A abordagem ingênua não é aplicável, pois a ordem não deve importar:

<!ELEMENT tasklist (title?, description?, task*) >

Como alternativa, eu poderia nomear explicitamente tudo Opções possíveis:

(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*)

Mas então é muito fácil escrever uma regra não determinística e, além disso, parece o caminho direto para a loucura mais sombria. Alguma idéia, como isso poderia ser feito com mais elegância?

E não, um XSD ou relaxamento não é opção. Eu preciso de um DTD simples e antigo.

Foi útil?

Solução

Isso resume o que você precisa:

<!ELEMENT tasklist (task*, ((title?, task*, description?) |
                    (description?, task*, title?)), task*)>

Alternância para o title aparecendo antes/depois description.

No entanto, este não é um modelo de conteúdo determinístico, como @13ren explica em sua resposta. [Aqui está outro exemplo da Microsoft] (http://msdn.microsoft.com/en-us/library/9bf3997x(vs.71).aspx).

Resumidamente

Seus requisitos são ter um modelo não determinístico e, como tal, não há não válido DTD para o seu cenário.

Alternativas

Se você colocar uma restrição simples que também task ou description deve ser o último elemento se ambos task e description são fornecidos, você pode usar esta declaração determinística do DTD:

<!ELEMENT tasklist (
  task*,
  ((title, task*, description?) | 
  (description, task*, title?))?
)>

Exemplos:

<!-- Valid -->
<tasklist>
  <task></task>
  <task></task>
  <task></task>
  <title></title>
  <task></task>
  <description></description>
</tasklist>
<!-- Valid -->
<tasklist>
  <title></title>
  <task></task>
  <task></task>
  <task></task>
</tasklist>
<!-- Invalid
<tasklist>
  <task></task>
  <title></title>
  <task></task>
  <description></description>
  <task></task>
</tasklist>
-->

Ou, possivelmente mais naturalmente, aplique que um title ou description elemento deve ser o primeiro elemento, e ambos title e description Os elementos devem existir ou não existentes.

<!ELEMENT tasklist (
  ((title, task*, description) | 
  (description, task*, title))?,
  task*
)>

Exemplos:

<!-- Valid -->
<tasklist>
  <title></title>
  <task></task>
  <description></description>
  <task></task>
  <task></task>
</tasklist>
<!-- Invalid
<tasklist>
  <task></task>
  <title></title>
  <description></description>
  <task></task>
  <task></task>
</tasklist>

<tasklist>
  <title></title>
  <task></task>
  <task></task>
  <task></task>
</tasklist>
-->

Por outro lado

Caso contrário, você precisa usar o relaxamento NG, o que permite modelos não determinísticos.

Outras dicas

Por que a ordem não é importante?

Parece -me que a ordem é um pouco importante aqui; e que o único sensível O pedido é o título?, descrição?, tarefa*.

A flexibilidade é boa e tudo, mas às vezes não é necessária.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top