Hier ist der geschäftliche Teil des Problems:
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?
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" 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!
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,
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.
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? , Ссылка
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 .
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:
Tags und Links c# design-patterns generics linq-to-xml