Каков наилучший подход для обобщения и агрегирования дампов XML в C #? - PullRequest
8 голосов
/ 17 декабря 2010

Вот бизнес-часть вопроса:

  • Несколько разных компаний отправляют дамп XML для обработки информации.
  • Информация, отправляемая компаниями, похожа... не совсем то же самое.
  • Вскоре будет привлечено еще несколько компаний, которые начнут отправлять информацию

Теперь техническая часть проблемы заключается в том, что я хочу написать общее решение вC # для размещения этой информации для обработки.Я хотел бы преобразовать XML в своем классе (ах) C #, чтобы он соответствовал моей модели базы данных.

Существует ли какой-либо шаблон или решение для этой проблемы, которое нужно обрабатывать в общем, без необходимости менять свое решение в случае добавленияо многих компаниях позже?

Как лучше всего написать мой анализатор / преобразователь?

Ответы [ 6 ]

11 голосов
/ 17 декабря 2010

Так я делал нечто подобное в прошлом.

Пока каждая компания имеет свой собственный фиксированный формат, который они используют для своего дампа XML,

  1. Определите XSLT для каждой компании.
  2. Иметь способ указать, из какого источника получен дамп (возможно, разные папки DUMP для каждой компании)
  3. В вашей программе на основе 2 выберите 1 и примените его к DUMP
  4. Все XSLT преобразуют XML в единую стандартную схему базы данных
  5. Сохраните это в своей БД

Каждое новое добавление компании - самое большее новый XSLT В тех случаях, когда схема очень похожа, XSLT можно просто повторно использовать, а затем вносить в них конкретные изменения.

Недостаток этого подхода: отладка XSLT может быть немного более болезненной, если у вас нет подходящих инструментов. Однако многие XML-редакторы (например, XML Spy и т. Д.) Имеют отличные возможности отладки XSLT.

2 голосов
/ 26 декабря 2010

Звучит так, будто вы просто запрашиваете шаблон проектирования (или набор шаблонов), который вы могли бы использовать, чтобы сделать это общим, ориентированным на будущее образом, верно?

В идеале некоторые из атрибутовчто вы, вероятно, хотите

  • Каждый «преобразователь» отделен друг от друга.
  • Вы можете легко добавлять новые «преобразователи» без необходимости переписывать основную подпрограмму «драйвера».
  • Вам не нужно перекомпилировать / повторно развертывать все ваше решение каждый раз, когда вы модифицируете трансформатор или, по крайней мере, добавляете новое.

Каждый «преобразователь» в идеале должен реализовывать общий интерфейсо которой знает ваша рутина драйвера - назовите ее IXmlTransformer.Ответственность этого интерфейса состоит в том, чтобы принять XML-файл и вернуть любую объектную модель / набор данных, который вы используете для сохранения в базе данных.Каждый из ваших преобразователей будет реализовывать этот интерфейс.Для общей логики, которая является общей для всех преобразователей, вы можете либо создать базовый класс, от которого все наследуют, либо (мой предпочтительный выбор) иметь набор вспомогательных методов, которые вы можете вызывать из любого из них.

Я быНачните с использования Factory, чтобы создать каждый «преобразователь» из вашей основной процедуры драйвера.Фабрика может использовать рефлексию для опроса всех сборок, которые она может видеть, или что-то вроде MEF, которая может сделать большую работу за вас.Ваша логика драйвера должна использовать фабрику для создания и преобразования всех преобразователей.

Затем вам понадобится некоторая логика и механизм для «поиска» каждого XML-файла, полученного для данного Transformer - возможно, у каждого XML-файла есть заголовок, которыйВы можете использовать, чтобы идентифицировать или что-то подобное.Опять же, вы хотите отделить их от своей основной логики, чтобы вы могли легко добавлять новые преобразователи без изменения процедуры драйвера.Например, вы можете предоставить файл XML каждому преобразователю и спросить его «можете ли вы преобразовать этот файл», и каждый преобразователь должен «взять на себя ответственность» за данный файл.

Каждый раз, когда ваша процедура драйвера получаетновый файл XML, он ищет соответствующий преобразователь и запускает его;результат отправляется в область обработки БД.Если преобразователь не найден, вы помещаете файл в каталог для последующего опроса.

Я бы порекомендовал прочитать книгу Роберта Мартина, такую ​​как Agile Principles, Patterns and Practices (http://www.amazon.co.uk/Agile-Principles-Patterns-Practices-C/dp/0131857258),), в которой приведены хорошие примерышаблоны проектирования для таких ситуаций, как ваша, например, Factory и DIP и т. д.

Надеюсь, это поможет!

1 голос
/ 27 декабря 2010

Использование XSLT, как предложено в наиболее востребованном ответе, просто перемещает проблему с c # на xslt.

Вы все еще изменяете части, которые обрабатывают xml, и вы все еще видите, насколько хорошо / плохо структурирован код / ​​находится ли он в c # или правилах в xslt.

Независимо от того, сохраняете ли вы его в c # или переходите на xslt для этих битов, ключ заключается в том, чтобы отделить преобразование xml, получаемого от различных компаний, в уникальный формат, будь то промежуточный xml или набор классов, в которых вы загрузить данные, которые вы обрабатываете.

Что бы вы ни делали, избегайте умничать и пытаться определить свой собственный общий уровень преобразования, если вы этого хотите. Используйте XSLT, поскольку именно для этого. Если вы идете с c #, оставьте это простым с классом преобразования для каждой компании, которая реализует самый простой интерфейс.

На пути c # сохраняйте любое повторное использование между преобразованиями в композицию, даже не думайте о наследовании, чтобы сделать это ... это одна из областей, где это становится очень уродливо быстро, если вы идете таким образом .

1 голос
/ 25 декабря 2010

Решение, предложенное InSane, похоже, является наиболее прямым и определенно дружественным XML-подходом.

Если вы хотите написать собственный код для преобразования различных форматов данных, а не для реализации нескольких объектов чтения, которые будут считывать данные из каждого отдельного формата и преобразовывать в унифицированный формат, то ваш основной код будет работать с этими объектами унифицированным способом, т.е. путем сохранения в базу данных.

Поиск ETL - (Extract-Trandform-Load) для получения дополнительной информации - Какую модель / шаблон следует использовать для обработки нескольких источников данных? , http://en.wikipedia.org/wiki/Extract,_transform,_load

0 голосов
/ 27 декабря 2010

Просто поиграйте здесь и предложите другое решение для других читателей.

Самый простой способ получить данные для ваших моделей в C # - использовать XSLT для преобразования данных каждой компании в сериализованную форму ваших моделей,Вот основные шаги, которые я бы предпринял:

  1. Создайте полную модель всех ваших данных и используйте XmlSerializer, чтобы выписать модель.
  2. Создайте XSLT, который берет данные Компании A и преобразует их в действительную сериализованную модель XML ваших данных.Используйте ранее созданный XML-файл в качестве ссылки.
  3. Используйте десериализацию для нового XML, который вы только что создали.Теперь у вас будет ссылка на объект вашей модели, содержащий все данные компании.
0 голосов
/ 26 декабря 2010

Рассматривали ли вы BizTalk сервер?

...