Подход к извлечению значений XML внутренней схемы для сопоставления с входящей схемой оркестровки - PullRequest
1 голос
/ 01 ноября 2008

Существует несколько систем приложений, которые передают сообщения друг другу как часть своего рабочего процесса. Из-за технических ограничений, нарушающих целостность транзакций, данные приложения и доставка сообщений фиксируются в единой базе данных DB2 мэйнфрейма. Сообщения не передаются напрямую на сервер BizTalk (2006 R2); позднее BTS сможет извлечь сообщение из базы данных DB2.

Таблица очереди сообщений в базе данных DB2 имеет несколько полей. Ключевым полем является столбец MESSAGE_DATA - фактическое сообщение; это сам контент XML. Когда кто-то использует адаптер DB2 для запроса записей из таблицы, входящая схема будет выглядеть как

ОБНОВЛЕНИЕ КОРРЕКЦИИ: схема DB2Message основана на атрибутах; Я ошибочно принял его за элементный базис.

<DB2Message MESSAGE_DATA="&lt;InternalXML&gt; ........ &lt;/InternalXML&gt;"
 MESSAGE_DATE="2008-1-1 00:00:00" MESSAGE_ID="GUID" TXN_ID="GUID" .... other attrib />

Оркестровка использует схему

<EAIMessage>
 <Header>
  <ServiceID>
  <MessageID>
  ....
  <Mode>
 </Header>
 <Body>
  <RawXML>
 </Body>
</EAIMessage>

Оркестровка будет использовать несколько повышенных полей в заголовке для принятия решений о маршрутизации и обработке. Дело в том, что эти поля заголовков на самом деле берутся из содержимого внутреннего XML, хранящегося в MESSAGE_DATA DB2Message.

На этом единственном уровне Mapper не знает об этой базовой XML-схеме внутри MESSAGE_DATA при объединении двух схем. Вероятно, должен быть какой-то функтоид XPath, который может дополнительно развернуть элемент MESSAGET_DATA для проведения правильного сопоставления значений, но, поскольку раньше я не имел дело с обширными приложениями XML и XSLT, я не могу увидеть доступные функции, которые могут помочь мне выполнить эту задачу .

Кто-нибудь делал такое извлечение и отображение данных раньше?

UPDATE. В соответствии с запросом, внутренний файл MESSAGE_DATA может выглядеть как

<Message>
    <Id>e86970f4-0455-4535-8e65-a06eb7aaef8a</Id>
    <SenderApp>999</SenderApp>
    <ReceiverApp>2000</ReceiverApp>
    <ServiceId>8798973454</ServiceId>
    <Mode>P</Mode>
    <MuxId></MuxId>
    <ExceptionCode></ExceptionCode>
    <ExceptionMessage></ExceptionMessage>
    <Body>
        <WorkItem xmlns="http://tempuri.org/WorkItem.xsd">
            <ServiceHeader xmlns="http://tempuri.org/Service.xsd">
                <ID_UPDATED_BY>username</ID_UPDATED_BY>
                <ID_HISTORY_REF>xxxxxxx</ID_HISTORY_REF>
                <SESSION_ID>sessionID</SESSION_ID>
                <DT_LAST_UPDATE>timestamp</DT_LAST_UPDATE>
                <TM_LAST_UPDATE>time</TM_LAST_UPDATE>
            </ServiceHeader>
        </WorkItem>
    </Body>
</Message>

Ответы [ 2 ]

1 голос
/ 06 декабря 2008

Крис прав: кажется, что вам важна только внутренняя часть сообщения, внешняя часть - просто конверт.

В качестве такового я бы предложил вам создать дизассемблер, который в приемном конвейере удалит конверт (вы можете сохранить его целиком как свойство контекста и / или извлечь некоторые биты из него как отдельные свойства, если вы необходимо воздействовать на них) и извлечь внутреннюю часть, которая станет сообщением, опубликованным в окне сообщения.

Теперь настоящее сообщение обрабатывается одним получателем, но остальная часть отправляющего порта и любого подписчика, а также любая информация, которую вы запрашиваете из конверта, передается вместе с ним через его контекст.

Теперь у вас есть полный доступ к сообщению и его свойствам; если применимо, вы можете развернуть схему для этого сообщения, которая может иметь отличительные свойства, которые обеспечат вам быстрый доступ к некоторым узлам (простого типа). в качестве альтернативы вы можете использовать xlang / s xpath для извлечения информации.

Если ваше встроенное сообщение было внутри элемента в конверте, вы наверняка могли бы использовать встроенный XmlDisassembler для всего этого (вам просто нужно правильно развернуть свои схемы и соответствующим образом настроить компонент; я не уверен, насколько хорошо это работает с сообщением, содержащимся в атрибуте, но, вероятно, стоит попробовать.

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

0 голосов
/ 05 декабря 2008

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

...