Was ist der beste Ansatz zum Generalisieren und Aggregieren von XML-Dumps in C #?

8

Hier ist der geschäftliche Teil des Problems:

  • Mehrere verschiedene Firmen senden a XML-Dump der Information zu sein verarbeitet.
  • Die von den Unternehmen gesendeten Informationen sind ähnlich ... nicht genau gleich.
  • Mehrere weitere Unternehmen würden bald kommen angeworben und würde anfangen zu senden Informationen

Jetzt ist der technische Teil des Problems, ich möchte eine generische Lösung in C # schreiben, um diese Information für die Verarbeitung unterzubringen. Ich würde die XML in meinen C # -Klasse (n) transformieren, um in mein Datenbankmodell zu passen.

Gibt es ein Muster oder eine Lösung für dieses Problem, das generisch gehandhabt werden kann, ohne meine Lösung ändern zu müssen, wenn später viele Firmen hinzukommen?

Was wäre der beste Ansatz, um meinen Parser / Transformer zu schreiben?

    
GilliVilla 17.12.2010, 02:08
quelle

6 Antworten

2

Klingt für mich so, als würden Sie nur nach einem Designmuster (oder einer Menge von Mustern) fragen, das Sie dazu verwenden könnten, dies auf generische, zukunftssichere Weise zu tun, oder?

Idealerweise einige der Attribute, die Sie wahrscheinlich möchten

  • Jeder "Transformator" ist voneinander entkoppelt.
  • Sie können ganz einfach neue "Transformatoren" hinzufügen, ohne die eigentliche "Treiber" -Routine neu schreiben zu müssen.
  • Sie müssen Ihre gesamte Lösung nicht jedes Mal neu kompilieren / implementieren, wenn Sie einen Transformer ändern oder mindestens einen neuen hinzufügen.

Jeder "Transformator" sollte idealerweise eine gemeinsame Schnittstelle implementieren, von der Ihre Treiberroutine weiß - nennen Sie sie IXmlTransformer. Die Verantwortung dieser Schnittstelle besteht darin, eine XML-Datei aufzunehmen und das Objektmodell / Dataset zurückzugeben, das Sie zum Speichern in der Datenbank verwenden. Jeder Ihrer Transformatoren würde diese Schnittstelle implementieren. Für allgemeine Logik, die von allen Transformatoren geteilt wird, könntest du entweder eine basierte Klasse erstellen, von der alle erben, oder (meine bevorzugte Wahl) habe eine Reihe von Hilfsmethoden, die du von jedem von ihnen aufrufen kannst.

Ich würde anfangen, indem ich eine Fabrik verwende, um jeden "Transformator" von deiner Hauptfahrerroutine zu erstellen. Die Fabrik könnte Reflektionen verwenden, um alle Baugruppen abzufragen, die sie sehen kann, oder etwas wie MEF, das einen großen Teil der Arbeit für Sie erledigen könnte. Ihre Treiberlogik sollte die Factory verwenden, um alle Transformer zu erstellen und sie zu speichern.

Dann brauchen Sie eine Logik und einen Mechanismus, um jede XML-Datei, die für einen bestimmten Transformer empfangen wird, zu "suchen" - vielleicht hat jede XML-Datei eine Kopfzeile, die Sie zum Identifizieren oder Ähnlichem verwenden könnten. Auch hier möchten Sie diese von Ihrer Hauptlogik entkoppelt halten, so dass Sie ohne Änderung der Treiberroutine problemlos neue Transformatoren hinzufügen können. Sie könnten z.B. Liefern Sie die XML-Datei an jeden Transformator und fragen Sie "Kannst du diese Datei transformieren", und es liegt an jedem Transformator, "Verantwortung für eine bestimmte Datei zu übernehmen".

Jedes Mal, wenn Ihre Treiberroutine eine neue XML-Datei erhält, sucht sie den entsprechenden Transformator und führt ihn durch; Das Ergebnis wird an den DB-Verarbeitungsbereich gesendet. Wenn kein Transformator gefunden werden kann, speichern Sie die Datei später in einem Verzeichnis für die Abfrage.

Ich würde empfehlen, ein Buch wie Agile Principles, Patterns and Practices von Robert Martin (http://www.amazon.co.uk/Agile-Principles-Patterns-Practices-C/dp/0131857258) zu lesen, was gut ist Beispiele für geeignete Entwurfsmuster für Situationen wie Ihres Fabrik und DIP etc.

Hoffe das hilft!

    
Isaac Abraham 26.12.2010, 15:35
quelle
11

So habe ich in der Vergangenheit etwas ähnliches gemacht.

Solange jede Firma ihr eigenes festes Format hat, das sie für ihren XML-Dump verwenden,

  1. Haben Sie eine spezifische XSLT für jede Firma.
  2. Sie können angeben, welcher Dump von wo her kommt (möglicherweise unterschiedliche DUMP-Ordner für jedes Unternehmen)
  3. Wählen Sie in Ihrem Programm basierend auf 2 1 aus und wenden Sie sie auf den DUMP
  4. an
  5. Alle XSLTs werden das XML in ein einziges Standard-Datenbankschema
  6. umwandeln
  7. Speichern Sie dies in Ihrer Datenbank

Jeder neue Firmenzusatz ist höchstens ein neues XSLT In Fällen, in denen das Schema sehr ähnlich ist, können die XSLTs einfach wiederverwendet und dann spezifische Änderungen an ihnen vorgenommen werden.

Nachteil dieses Ansatzes: Das Debuggen von XSLTs kann etwas schmerzhafter sein, wenn Sie nicht über die richtigen Tools verfügen. Viele XML-Editoren (z. B. XML Spy usw.) verfügen jedoch über hervorragende XSLT-Debugging-Funktionen.

    
InSane 17.12.2010 02:40
quelle
1

Die von InSane vorgeschlagene Lösung ist der geradlinigste und definitiv XML-freundliche Ansatz.

Wenn Sie Ihren eigenen Code schreiben möchten, um die Konvertierung verschiedener Datenformate durchzuführen, anstatt mehrere Reader-Entities zu implementieren, die Daten aus jedem einzelnen Format lesen und in ein einheitliches Format umwandeln würden, würde Ihr Hauptcode mit diesen Entities einheitlich arbeiten. zB durch Speichern in der Datenbank.

Suchen Sie nach ETL - (Extract-Trandform-Load), um weitere Informationen zu erhalten - Welches Modell / Muster soll ich für den Umgang mit mehreren Datenquellen verwenden? , Ссылка

    
Alexei Levenkov 25.12.2010 03:16
quelle
1

Die Verwendung von XSLT, wie in der aktuell am meisten aktualisierten Antwort vorgeschlagen, verschiebt das Problem nur von c # nach xslt.

Sie ändern immer noch die Teile, die das XML verarbeiten, und Sie sind immer noch der Tatsache ausgesetzt, wie gut / schlecht der Code strukturiert ist / ob er sich in c # oder Regeln in der xslt befindet.

Unabhängig davon, ob Sie es in c # behalten oder für diese Bits verwenden, besteht der Schlüssel darin, die Umwandlung des von den verschiedenen Unternehmen erhaltenen XML in ein eindeutiges Format zu trennen, unabhängig davon, ob es sich um ein Zwischen-XML oder eine Gruppe von Klassen handelt lade die Daten, die du verarbeitest.

Was auch immer Sie tun, vermeiden Sie, clever zu werden und versuchen Sie, Ihre eigene generische Transformationsebene zu definieren, wenn Sie das wollen. Verwenden Sie XSLT, denn das ist es. Wenn Sie mit c # arbeiten, halten Sie es einfach mit einer Transformationsklasse für jede Firma, die die einfachste Schnittstelle implementiert.

Halten Sie bei der c # -Weise die Wiederverwendung, die Sie zwischen den Umwandlungen haben, in Komposition, denken Sie nicht einmal an Vererbung, um dies zu tun ... Dies ist einer der Bereiche, in denen es sehr hässlich wird, wenn Sie diesen Weg gehen .

    
eglasius 27.12.2010 15:23
quelle
0

Haben Sie BizTalk Server in Betracht gezogen?

    
fejesjoco 26.12.2010 14:51
quelle
0

Hier einfach den Zaun spielen und anderen Lesern eine andere Lösung anbieten.

Der einfachste Weg, um die Daten in Ihre Modelle in C # zu bekommen, ist die Verwendung von XSLT, um die Daten jedes Unternehmens in eine serialisierte Form Ihrer Modelle zu konvertieren. Dies sind die grundlegenden Schritte, die ich ergreifen würde:

  1. Erstellen Sie ein vollständiges Modell aller Daten und verwenden Sie den XmlSerializer, um das Modell auszugeben.
  2. Erstellen Sie ein XSLT, das die Daten von Unternehmen A in ein gültiges serialisiertes XML-Modell Ihrer Daten konvertiert. Verwenden Sie die zuvor erstellte XML-Datei als Referenz.
  3. Verwenden Sie Deserialize für das neue XML, das Sie gerade erstellt haben. Sie haben jetzt einen Verweis auf Ihr Modellobjekt, das alle Daten des Unternehmens enthält.
Andrew T Finnell 27.12.2010 18:12
quelle