Pregunta

Tengo una aplicación que guarda documentos (piense en documentos de Word) en un formato basado en Xml. Actualmente, las clases de C # generadas a partir de archivos xsd se usan para leer / escribir el formato del documento y todo estaba bien hasta hace poco cuando tuve que hacer un cambio El formato del documento. Mi preocupación es la compatibilidad con versiones anteriores, ya que las versiones futuras de mi aplicación necesitan para poder leer documentos guardados en todas las versiones anteriores e idealmente también quiero que las versiones anteriores de mi aplicación puedan manejar con gracia la lectura de documentos guardados por versiones futuras de mi aplicación.

Por ejemplo, suponiendo que cambie el esquema de mi documento para agregar un elemento adicional (opcional) en algún lugar, las versiones anteriores de mi aplicación simplemente ignorarán el elemento adicional y no habrá problemas:

<doc>
    <!-- Existing document -->
    <myElement>Hello World!</myElement>
</doc>

Sin embargo, si se realiza un cambio importante (un atributo se cambia a un elemento, por ejemplo, o una colección de elementos), las versiones anteriores de mi aplicación deberían ignorar este elemento si es opcional o informar al usuario que de lo contrario, intento leer un documento guardado con una versión más reciente de mi aplicación. Además, actualmente esto me está causando dolores de cabeza, ya que todas las versiones futuras de mi aplicación necesitan un código totalmente independiente para leer los dos documentos diferentes.

Un ejemplo de tal cambio sería el siguiente xml:

<doc>
    <!-- Existing document -->
    <someElement contents="12" />
</doc>

Cambiando a:

<doc>
    <!-- Existing document -->
    <someElement>
        <contents>12</contents>
        <contents>13</contents>
    </someElement>
</doc>

Para evitar dolores de cabeza de soporte en el futuro, quería idear una estrategia decente para manejar los cambios que podría hacer en el futuro, para que las versiones de mi aplicación que lanzo ahora puedan hacer frente a estos Cambios en el futuro:

  • ¿Debería el " número de versión " El documento debe almacenarse en el mismo documento y, en caso afirmativo, ¿qué estrategia de control de versiones debe utilizarse? Si la versión del documento coincide con la versión del ensamblado .exe, o si se usa una estrategia más compleja, (por ejemplo, una revisión importante modificada indica cambios importantes, mientras que los incrementos menores de la revisión indican cambios continuos, por ejemplo, elementos opcionales adicionales)
  • ¿Qué método debo usar para leer el documento en sí y cómo evitar la replicación de cantidades masivas de código para diferentes versiones de documentos?
    • Aunque XPath es obviamente más flexible, es mucho más trabajo de implementar que simplemente generar clases con xsd.
    • Por otra parte, si se usa el análisis de DOM, entonces se necesitará una nueva copia del documento xsd en el control de origen para cada cambio de ruptura, lo que causará problemas si alguna vez se deben aplicar arreglos a esquemas más antiguos (las versiones anteriores de la aplicación son todavía compatible).

También, he trabajado todo esto de manera muy holgada en el supuesto de que todos los cambios que realice se pueden dividir en estas dos categorías de " beaking changes " y "cambios que no rompen", pero no estoy del todo convencido de que esta es una suposición segura.

Tenga en cuenta que uso el término " documento " muy libremente: el contenido no se parece en nada a un documento!

Gracias por cualquier consejo que me puedan ofrecer.

¿Fue útil?

Solución

Definitivamente necesita un número de versión en el archivo XML, y sugeriría no vincularlo a la versión de la aplicación porque es realmente una entidad separada. Puede usar dos o tres versiones de su aplicación sin cambiar el formato XML o puede terminar cambiando el formato varias veces durante el desarrollo de una única versión.

Si desea que las versiones anteriores de la aplicación puedan leer versiones más nuevas del archivo XML, nunca podrá eliminar elementos ni cambiar sus nombres. Siempre puede agregar elementos y el código anterior los ignorará (una de las buenas características de XML), pero si los elimina, el código anterior no podrá funcionar.

Como dijo Ishmael, XSLT es una buena manera de convertir el formato XML de una versión a otra para que no termines con un montón de rutinas de análisis en tu código fuente.

Otros consejos

XSLT es una opción obvia aquí. Dado que puede identificar la versión de su documento, para cada versión de su esquema, cree un XSLT que transforme la versión anterior a su nueva versión.

Puede aplicar las transformaciones en secuencia hasta que alcance la versión actual. Por lo tanto, solo está editando la última versión del documento. Por supuesto, no podrá guardar en el formato anterior y puede romper el documento para versiones anteriores, pero esto es típico de muchas aplicaciones. Si realmente necesita guardar en la versión anterior, simplemente cree una transformación que vaya al revés.

Como dice @Andy, usa el número de compilación principal de tu aplicación.

¿Podría agregar un atributo al elemento raíz que especifica la versión?

De esta manera, las versiones anteriores no se romperán, y las versiones más recientes de su software verán el atributo y cambiarán a un método de carga diferente de manera apropiada.

La numeración de la versión dependerá de su frecuencia de lanzamiento. Yo personalmente iría con el número de compilación principal de su software, a menos que prevea que el formato cambie con más frecuencia que eso.

Editar : acabo de notar un poco sobre la duplicación de código:

Para eso usaría el Patrón de Fábrica, algo como esto:

LoadDocument
DoNonVersionDependingLoading
VersionSpecificLoaderFactory(VersionNumber)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top