2011-01-20 116 views
15

Empecé utilizando un archivo XML y un analizador como una forma conveniente para almacenar los datos de miXML, DTD: cómo hacer que el orden no es importante

quiero usar DTD para comprobar la estructura de los archivos XML cuando ellos llegan.

Aquí está mi archivo 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)> 

(tenga en cuenta que FileNumber nombre de archivo y en realidad son puramente opcional)

y

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

como tal, todo esto funciona bien. (Utilizo eclipse "validar" la opción para poner a prueba todo por ahora)

Sin embargo, mientras que las pruebas que tengo lo que creo que es un error extraño

si hago

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

cambiar el orden de las líneas , Eclipse se niega a validarlo ...

Me preguntaba si esto era un problema con Eclipse o si el pedido es realmente importante.

Si el orden es importante, ¿cómo puedo cambiar la DTD para que funcione sin importar el orden de los elementos?

Realmente no puedo cambiar el XML porque ya tengo todos los archivos XML y el analizador escrito (sé que lo hice al revés, lol).

Respuesta

8

Como dijo Roger, no están clasificadas solamente las listas, pero se puede utilizar el operador O | para definir todas las combinaciones aceptadas

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

Look here, hay un ejemplo de la sección opciones

+0

hum ... Hubiera pensado que sería más flexible ... Tendré que irme con || porque tuve que hacer suposiciones sobre el orden en que se lee el xml lol. gracias por la solución –

+4

Esta no es una DTD válida porque no es determinista. Incluso si fuera válido, no permitiría los elementos secundarios en ningún orden posible. – jasso

4

Con una DTD, los nodos secundarios deben aparecer en el orden indicado en la definición del elemento. No hay forma de permitir pedidos alternativos, a menos que desee actualizar a un esquema XSD.

Adición: Por @Gaim, que puede órdenes oferta alternativa utilizando el (a, b, c ...) | (b, a, c ...) la sintaxis, pero esto no es realmente práctico para obtener más que, digamos, 3 elementos anidados, ya que un orden arbitrario permite un número factorial de ordenamientos - 6 para 3 elementos, 24 para 4 elementos, 120 para 5 elementos - y un uso inteligente de? operadores seguramente dará como resultado una validación falsa para casos extraños.

+0

es un sistema realmente pequeño, así que no creo que sea interesante cambiar a XSD, pero lo voy a ver gracias –

+1

No es estrictamente cierto. Puede permitir pedidos alternativos, solo tiene que enumerar explícitamente todos los que desea permitir. No hay una gran diferencia entre las reglas de ordenamiento permitidas en el esquema XML y una DTD, es simplemente menos doloroso expresarlas en un esquema. –

8

La declaración de listas desordenadas con limitaciones de ocurrencia en DTD a menudo dará como resultado declaraciones de apariencia largas o complicadas. Una razón importante para esto es que las DTD deben ser deterministas, por lo tanto, incluso cambiar a esquemas XML no necesariamente ayuda.

Aquí es una declaración DTD para el elemento <level> que contiene:

  • exactamente 1 <file> elemento
  • 0-1 <fileName> elementos
  • 0-1 <fileNumber> elementos
  • en cualquier orden posible

código:

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

Puede utilizar ANY palabra clave si no se molestan demasiado acerca de la validez:

<!ELEMENT level ANY> 

me he enfrentado a un problema similar here, pueden aparecer estos dos casos:

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

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

La única solución que encontré fue la siguiente:

<!ELEMENT Instructors ANY> 

Quizás haya una solución mejor, pero funciona bien para mi problema en particular.

+6

Será mejor usar:

+0

Parece. Hace un año no pude encontrar una mejor idea. – rendon

+1

Parece que estabas haciendo el Ejercicio XML de la base de datos de Stanford MOOC por Jennifer Widom ... Llegué aquí por el mismo problema :-) Con Ya no recibo ningún error de xmllint . –

0

Si puede adivinar el límite superior sensible para el número de hijos para su elemento, entonces hay una manera extremadamente sucia de cómo solucionar el problema. Sigue el ejemplo para los niños 0-3:

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

Por lo tanto, permitir que el elemento "myUnorderedElement" que tiene 0-3 niños de cualquier tipo de option1, opcion2 o opción3.

Cuestiones relacionadas