2010-12-17 16 views
8

Aquí es la parte del negocio de la edición:¿Cuál es el mejor enfoque para generalizar y agregar volcados de XML en C#?

  • Varias compañías diferentes envían un vertedero XML de la información que se procesa .
  • La información enviada por las empresas son similares ... no exactamente iguales.
  • Varias empresas serían más pronto alistaron y se comenzaría a enviar la información

Ahora, la parte técnica del problema es que quiero escribir una solución genérica en C# para dar cabida a esta información para su procesamiento. Transformaría el XML en mi (s) clase (s) C# para adaptarme a mi modelo de base de datos.

¿Existe algún patrón o solución para manejar este problema de forma genérica sin necesidad de cambiar mi solución en caso de que se agreguen muchas compañías más adelante?

¿Cuál sería el mejor enfoque para escribir mi analizador sintáctico/transformador?

+0

¿Al menos una compañía específica tendrá el mismo formato cada vez que envíe un volcado o puede ser diferente para diferentes volcados? – InSane

+0

Puede generar un xsd del xml y luego un modelo de clase del archivo xsd usando la herramienta xsd de .NET. Y luego crea un ensamblaje para este tipo y cárgalo utilizando el reflejo en tu aplicación. El uso de la clase en la aplicación volvería a utilizar la reflexión para consultar a los miembros, crear instancias y asignar valores. –

Respuesta

2

Me parece que está pidiendo un patrón de diseño (o un conjunto de patrones) que podría utilizar para hacer esto de una manera genérica, a prueba de futuro, ¿no?

Lo ideal sería que algunos de los atributos que es probable que desee

  • Cada "transformador" se desacopla el uno del otro.
  • Puede agregar fácilmente nuevos "transformadores" sin tener que volver a escribir su rutina principal de "controlador".
  • No necesita recompilar/volver a implementar su solución completa cada vez que modifique un transformador, o al menos agregue uno nuevo.

Cada "transformador" idealmente debería implementar una interfaz común que su rutina de controladores conozca - llámela IXmlTransformer. La responsabilidad de esta interfaz es tomar un archivo XML y devolver cualquier modelo de objeto/conjunto de datos que utilice para guardar en la base de datos. Cada uno de sus transformadores implementaría esta interfaz. Para la lógica común compartida por todos los transformadores, puede crear una clase basada en la que todos hereden, o (mi opción preferida) tener un conjunto de métodos auxiliares a los que puede llamar desde cualquiera de ellos.

Comenzaría utilizando una fábrica para crear cada "transformador" de la rutina principal del controlador. La fábrica podría usar la reflexión para interrogar a todas las asambleas que pueda ver, o algo como MEF, que podría hacer mucho por usted. Su lógica de controlador debe usar la fábrica para crear todos los transformadores y almacenarlos.

Luego necesita un poco de lógica y mecanismo para "buscar" cada archivo XML recibido en un Transformador dado; quizás cada archivo XML tenga un encabezado que podría usar para identificar o algo similar. De nuevo, desea mantener estos desacoplados de su lógica principal para que pueda agregar fácilmente nuevos transformadores sin modificar la rutina del controlador. Podría, por ejemplo, suministre el archivo XML a cada transformador y pregúntele "¿puede transformar este archivo?" y depende de cada transformador "responsabilizarse" de un archivo determinado.

Cada vez que su rutina de controlador obtiene un nuevo archivo XML, busca el transformador apropiado y lo ejecuta; el resultado se envía al área de procesamiento de DB. Si no se puede encontrar ningún transformador, vuelque el archivo en un directorio para su posterior interrogación.

Yo recomendaría leer un libro como Principios, patrones y prácticas ágiles por Robert Martin (http://www.amazon.co.uk/Agile-Principles-Patterns-Practices-C/dp/0131857258), que da buenos ejemplos de patrones de diseño apropiados para situaciones como la suya, por ejemplo Fábrica y DIP, etc.

Espero que ayude!

+0

+1 para dar algunas ideas de diseño: esta respuesta + las otras 2 deben ser = una buena solución para @GilliVilla – user44298

+0

Después de crear los transformadores ... ¿dónde sugieres? para almacenarlos? – GilliVilla

+0

Una opción simple es crear una clase pública estática que sea tu fábrica. Al inicializar la fábrica, debe buscar los transformadores y luego almacenarlos como una variable de nivel de clase estática privada, p. Lista . Luego, tenga un método en la fábrica como "GetAllTransformers", etc. –

11

Así es como he hecho algo similar en el pasado.

Mientras cada empresa tiene su propio formato fijo que utilizan para su volcado XML,

  1. Tener una XSLT específica para cada empresa.
  2. tienen una manera de indicar cuales volcado se obtiene de donde (tal vez diferentes carpetas de vaciado por cada empresa)
  3. En su programa, sobre la base de 2, seleccione 1 y lo aplican al vertedero
  4. Todo el XSLT transformará el XML a su un esquema de base de datos estándar
  5. Guardar este a su base de datos

Cada nueva adición empresa es a lo sumo un nuevo XSLT en los casos en que el esquema es muy similar, del XSLT puede ser simplemente re- utilizado y luego cambios específicos hechos a ellos.

Desventaja de este enfoque: Depurar XSLT puede ser un poco más doloroso si no tiene las herramientas adecuadas. Sin embargo, MUCHOS editores XML (por ejemplo, XML Spy, etc.) tienen excelentes capacidades de depuración XSLT.

+0

@InSane No solo estoy buscando el concepto de XSLT ... sino cómo esto puede manejarse genéricamente en C# – GilliVilla

+0

@GilliVilla: su pregunta sí habló sobre un patrón/solución genérica. Ahora, me temo que no entiendo muy bien lo que intentas indicar. – InSane

+0

@GilliVilla Usted solicitó una solución que no requirió que cambiara su solución. Como va a agregar diferentes tipos de XML más adelante, obviamente tendrá que cambiar ALGO. Si no está externalizando los cambios, ¿cómo quiere evitar cambios en el código? – Stefan

1

La solución propuesta por InSane es probablemente la más directa y definitivamente amigable con XML.

Si busca escribir su propio código para hacer conversiones de formatos de datos diferentes que implementar múltiples entidades lectoras que leerían datos de cada formato distinto y se transformaría en formato unificado, su código principal funcionaría con estas entidades de forma unificada , es decir, guardando en la base de datos.

Buscar ETL - (Extract-Trandform-Load) para obtener más información - What model/pattern should I use for handling multiple data sources?, http://en.wikipedia.org/wiki/Extract,_transform,_load

+0

+1 Definitivamente un problema de ETL, InSane ofrece una buena solución – user44298

1

El uso de XSLT como se propone en la respuesta actualmente más votada, es simplemente mover el problema, de C# a xslt.

Todavía está cambiando las piezas que procesan el xml, y todavía está expuesto a qué tan bueno/pobre es el código estructurado/si está en C# o reglas en el xslt.

Independientemente de si lo mantiene en C# o vaya xslt para esos bits, la clave es separar la transformación del xml que recibe de las diversas compañías en un formato único, ya sea un xml intermedio o un conjunto de clases donde usted carga los datos que está procesando.

Hagas lo que hagas evitando ser inteligente y tratando de definir tu propia capa de transformación genérica, si eso es lo que quieres. Utiliza XSLT ya que eso es para lo que es.Si usa C#, manténgalo simple con una clase de transformación para cada empresa que implemente la interfaz más simple.

En el modo C#, conserve cualquier reutilización que pueda tener entre las transformaciones de la composición, ni siquiera piense en la herencia para hacerlo ... esta es una de las áreas donde se pone muy feo rápidamente si se va camino.

0

Simplemente jugando la valla aquí y ofreciendo otra solución para otros lectores.

La manera más fácil de obtener los datos en sus modelos dentro de C# es usar XSLT para convertir los datos de cada compañía en una forma serializada de sus modelos. Estos son los pasos básicos que tomaría:

  1. Cree un modelo completo de todos sus datos y use XmlSerializer para escribir el modelo.
  2. Cree un XSLT que tome los datos de la compañía A y los convierta en un modelo xml serializado válido de sus datos. Use el archivo XML creado anteriormente como referencia.
  3. Use Deserialize en el nuevo XML que acaba de crear. Ahora tendrá una referencia a su objeto modelo que contiene todos los datos de la empresa.
Cuestiones relacionadas