2011-01-20 10 views
15

Ho cominciato usando un file XML e un parser come un modo conveniente per memorizzare i miei datiXML, DTD: come rendere l'ordine non è importante

voglio usare DTD per controllare la struttura dei file XML quando arrivano.

Ecco il mio file DTD

< ?xml version="1.0" encoding="UTF-8"?> 
< !ELEMENT document (level*)> 
< !ELEMENT level (file,filelName?,fileNumber?)> 
< !ELEMENT file (#PCDATA)> 
< !ELEMENT filelName (#PCDATA)> 
< !ELEMENT fileNumber (#PCDATA)> 

(notare che fileName e FileNumber sono in realtà puramente opzionale)

e

<document> 
<level> 
    <file>group1file01</file> 
</level> 
<level> 
    <file>group1file02</file> 
    <fileName>file 2</fileName> 
    <fileNumber>0</fileNumber> 
</level> 
... 

in quanto tale, tutto questo funziona bene. (Io uso Eclipse "validare" per provarlo per ora)

tuttavia durante il test ho ottenuto quello che penso sia un errore strano

se faccio

<level> 
    <levelName>Level 2</levelName> 
    <levelNumber>0</levelNumber> 
     <file>group1level02</file> 
</level> 

cambiando l'ordine delle linee , Eclipse rifiuta di convalidarlo ...

Mi chiedevo se si trattava di un problema con Eclipse o se l'ordine è effettivamente importante.

Se l'ordine è importante, come posso modificare il DTD per farlo funzionare, indipendentemente dall'ordinamento degli elementi?

Non riesco a modificare l'XML perché ho già tutti i file XML e il parser scritto (so che l'ho fatto nel modo sbagliato lol).

risposta

8

Come ha detto Roger, ci sono ordinate solo le liste, ma è possibile utilizzare operatore o | per definire tutte le combinazioni accettati

<!ELEMENT level ((file,filelName?,fileNumber?)|(filelName?,fileNumber?,file))> 

sguardo here, c'è un esempio nella sezione Scelte

+0

hum ... avrei pensato che sarebbe stato più flessibile ... dovrò andare con || perché dovevo fare assunzioni sull'ordine in cui xml è lol lol. grazie per la soluzione –

+4

Questo non è un DTD valido perché non è deterministico. Anche se fosse valido, non permetterebbe agli elementi figli in alcun ordine possibile. – jasso

4

Con un DTD i nodi figlio devono apparire nell'ordine elencato nella definizione dell'elemento. Non è possibile consentire ordini alternativi, a meno che non si desideri eseguire l'aggiornamento a uno schema XSD.

Addendum: Per @Gaim, è può offrire ordini alternativi utilizzando la sintassi (a, b, c ...) | (b, a, c ...), ma questo non è davvero pratico per ulteriori di, ad esempio, 3 elementi annidati, poiché un ordine arbitrario consente un numero fattoriale di ordinamenti - 6 per 3 elementi, 24 per 4 elementi, 120 per 5 elementi - e un uso intelligente di? gli operatori sono sicuri di portare a false convalide per casi strani.

+0

è per un sistema veramente piccolo quindi non penso che sarebbe interessante passare a XSD ma lo esaminerò grazie –

+1

Non strettamente vero. Puoi consentire ordini alternativi, devi solo elencare esplicitamente tutti quelli che vuoi consentire. Non c'è una grande differenza tra le regole di ordinamento consentite nello schema XML e una DTD, è semplicemente meno doloroso esprimerle in uno schema. –

8

Dichiarare liste non ordinate con vincoli di occorrenza nella DTD spesso porta a dichiarazioni lunghe o complicate. Uno dei motivi principali è che i DTD devono essere deterministici, quindi anche il passaggio a XML Schema non aiuta necessariamente.

Ecco una dichiarazione DTD per l'elemento <level> che contiene:

  • esattamente 1 <file> elemento
  • 0-1 <fileName> elementi
  • 0-1 <fileNumber> elementi
  • in qualsiasi ordine possibile

codice:

<!ELEMENT level ((file, ((fileName, fileNumber?) | (fileNumber, fileName?))?) 
       |(fileName, ((file, fileNumber?) | (fileNumber, file))) 
       |(fileNumber, ((file, fileName?) | (fileName, file))))> 
6

È possibile utilizzare ANY parola chiave se non si preoccupano troppo di validità:

<!ELEMENT level ANY> 

Ho affrontato un problema simile here, potrebbe essere visualizzata questa due casi:

<Instructors> 
    <Lecturer> 
    </Lecturer> 
    <Professor> 
    </Professor> 
</Instructors> 

<Instructors> 
    <Lecturer> 
    </Lecturer> 
    <Professor> 
    </Professor> 
</Instructors> 

L'unica soluzione che ho trovato è stata questa:

<!ELEMENT Instructors ANY> 

Forse c'è una soluzione migliore, ma funziona bene per il mio particolare problema.

+6

Sarà meglio usare:

+0

Quindi sembra. Un anno fa non sono riuscito a trovare un'idea migliore. – rendon

+1

Sembra che steste facendo l'Esercizio XML del database di Stanford MOOC di Jennifer Widom ... Sono arrivato qui a causa dello stesso problema :-) Con Non ricevo più errori da xmllint . –

0

Se riesci a indovinare il limite superiore sensibile per il numero di figli per il tuo elemento, allora c'è un modo estremamente sporco per superare il problema. Segue l'esempio per i bambini 0-3:

<!ELEMENT myUnorderedElement ((option1 | option2 | option3)?, (option1 | option2 | option3)?, (option1 | option2 | option3)? > 

Così, si consentirà l'elemento "myUnorderedElement" per avere 0-3 bambini di qualsiasi tipo di opzione1, opzione2 o Option3.

Problemi correlati