Мне нужна моя карта BizTalk, чтобы прекратить преобразование xml:lang в ns1:lang

У меня есть карта в BizTalk 2009, которая преобразует некоторые данные в документ XML для отправки в другую систему. Целевая схема включает в себя некоторые элементы с xml:lang атрибутов. BizTalk генерирует их как ns1:lang, Целевая система требует, чтобы префикс xml использоваться.

Вот упрощенный пример, чтобы показать, что делает BizTalk:

sample.xsd

<xs:schema targetNamespace="http://example.com/"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import schemaLocation="common.xsd"
             namespace="http://www.w3.org/XML/1998/namespace" />
  <xs:element name="example">
    <xs:complexType>
      <xs:attribute ref="xml:lang" />
    </xs:complexType>
  </xs:element>
</xs:schema>

common.xsd

<xs:schema xmlns:xml="http://www.w3.org/XML/1998/namespace"
           targetNamespace="http://www.w3.org/XML/1998/namespace"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:attribute name="lang" type="xs:language" />
</xs:schema>

Пример вывода карты

<ns0:example xmlns:ns0="http://example.com/"
             xmlns:ns1="http://www.w3.org/XML/1998/namespace"
             ns1:lang="en-US" />

Есть ли способ убедить BizTalk использовать xml префикс?

3 ответа

Решение

Насколько я знаю, нет никакого встроенного пути для достижения этого.

Однако есть два решения, которые я вижу:

Используйте пользовательскую таблицу стилей XML

Если вы щелкнете правой кнопкой мыши по карте и внимательно посмотрите на сгенерированную таблицу стилей xsl, вы увидите объявление пространства имен XML, например:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://www.w3.org/XML/1998/namespace"
                ...
                >
...
<xsl:attribute name="ns1:lang">
...

Это стандартное поведение сопоставителя BizTalk, и вы ничего не можете с этим поделать. Однако, если вы продолжите извлекать сгенерированный XSLT и использовать его в качестве бэкенда для своей карты, вы можете изменить это объявление, чтобы оно соответствовало ожидаемому результату.

  • Сначала скопируйте таблицу стилей в местоположение вашего проекта.
  • Включить эту таблицу стилей в виде файла в ваш проект BizTalk
  • Обновите таблицу стилей, чтобы объявление пространства имен и соответствующий префикс атрибута были правильными.

Результирующая таблица стилей xsl выглядит следующим образом:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xml="http://www.w3.org/XML/1998/namespace"
                ...
                >
...
<xsl:attribute name="xml:lang">
...

Теперь вы можете использовать эту пользовательскую таблицу стилей в качестве бэкенда для карты.

  • В Visual Studio откройте карту.
  • Щелкните в любом месте пустого пространства на поверхности конструктора BizTalk.
  • В свойствах карты найдите Custom XSL Path и укажите местоположение вашей пользовательской таблицы стилей.

Пользовательский путь BizTalk Mapper XSL

Используйте пользовательский компонент конвейера

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

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

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

Самый простой способ сделать это и заставить все работать - просто добавить объявление пространства имен в начале определения схемы, как это.

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xml="http://www.w3.org/XML/1998/namespace">
  <xs:import schemaLocation="xml.xsd" namespace="http://www.w3.org/XML/1998/namespace" />

В дополнение к предложениям Максима, есть и другие возможности, которые я нашел:

Не обращайте на это внимания и надейтесь, что API вендора возьмется за это.

Я не думаю, что это сработает. Когда я тестирую карту, BizTalk выдает мне эту ошибку:

Output validation error: Prefix 'ns1' cannot be mapped to namespace name reserved for "xml" or "xmlns".

Здравствуйте, BizTalk!? Вы тот, кто решил использовать ns1. Не жалуйся на это мне!

Используйте основанный на XSL сценарий functoid для форсирования вывода.

Это основано на предложении, которое я получил на форумах BizTalk. Это требует, чтобы мы выдумали выходную схему, чтобы использовать фиктивный атрибут, который заменяется атрибутом xml:lang на functoid.

Добавить выражение поиска / замены

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

Другие вопросы по тегам