BizTalk HL7 ошибка конвейера отправки из-за разрывов строк в пустых XML-элементах - PullRequest
1 голос
/ 21 февраля 2012

Я сопоставляю сообщение HL7 A31 с помощью сопоставителя BizTalk. На карте есть несколько встроенных функций сценариев XSLT.

Когда XML передается через конвейер отправки HL7, он генерирует ошибку:

Элемент 'ROL_11_OfficeHomeAddress' имеет недопустимую структуру

Если я посмотрю на приостановленное сообщение, я пойму, почему это произошло. Элемент ROL_11 пуст и выглядит следующим образом:

    <ROL_11_OfficeHomeAddress>
    </ROL_11_OfficeHomeAddress>

Между открывающим и закрывающим тегами есть разрыв строки и несколько пробелов / табуляций из-за отступа. Это именно то, что генерируется XSLT, и я считаю, что именно разрыв строки вызывает ошибку.

Я мог бы обернуть XSLT в оператор <xsl:if>, чтобы проверить значение перед написанием XML. Однако эта проблема встречается во многих местах, и кажется, что оборачивать каждый элемент, как этот, излишне.

Мне действительно нужно, чтобы BizTalk автоматически преобразовал элемент в пустой, например:

<ROL_11_OfficeHomeAddress />

Я верю, что это решит проблему. Есть ли способ, которым я могу сказать это, чтобы сделать это?

Вещи, которые я уже пробовал:

  • Использование <xsl:strip-space>, но возникла собственная ошибка. Я думаю, что это потому, что BizTalk оборачивает встроенный XSLT в свой собственный код, и, таким образом, пространство-полосы было указано в неправильном месте.

  • Изменение свойств сетки карты для установки Отступ на Нет в надежде на удаление пробела. Это никак не повлияло на XML, отображаемый в приостановленном сообщении.

  • Добавление раздела реестра для устаревшей обработки пробелов согласно этого руководства . Опять же, это, похоже, никак не отразилось.

Ответы [ 2 ]

1 голос
/ 03 декабря 2013

У меня тоже недавно была эта проблема, но в BizTalk 2013. Мы переместили все в пользовательские XSLT-файлы для отображения нашего HL7v2.После обновления до 2013 внезапно <xsl:strip-space>, который ранее работал, больше не работал.

Это происходит потому, что BizTalk 2013 теперь использует класс XslCompiledTransform, а не устаревший теперь класс XslTransform и не позволяет <xsl:strip-space>.Поэтому я тоже не столкнулся с каким-либо глобальным способом удаления пробелов.

Однако, после долгих поисков и расчесывания головы, я нашел неясное сообщение в блоге с чем-то, что сработало для моего решения:

http://geekswithblogs.net/peterbrouwer/archive/2012/08/17/biztalk-2010ndashlegacy-whitespace-behaviour.aspx

Опция в настройках Хоста для использования устаревших пробелов сделала это для нас (пока, по крайней мере).

1 голос
/ 21 февраля 2012

Если вы преобразуете всю свою карту в XSLT , ниже будут зачеркнуты новые строки и пробелы и оставлены пустые теги, если нет ничего, кроме пробелов:

<xsl:element name="ROL_11_OfficeHomeAddress">
  <xsl:if test="normalize-space(ROL_11_OfficeHomeAddress)">
    <xsl:value-of select="normalize-space(ROL_11_OfficeHomeAddress)" />
  </xsl:if>
</xsl:element>

Редактировать : Biztalk обычно генерирует XSLT, как показано ниже, в типичном отображении 1: 1 nillable element

    <xsl:variable name="var:v2" select="string(ns0:ROL_11_OfficeHomeAddress/@xsi:nil) = 'true'" />
    <xsl:if test="string($var:v2)='true'">
      <ns0:ROL_11_OfficeHomeAddress>
        <xsl:attribute name="xsi:nil">
          <xsl:value-of select="'true'" />
        </xsl:attribute>
      </ns0:ROL_11_OfficeHomeAddress>
    </xsl:if>
    <xsl:if test="string($var:v2)='false'">
      <ns0:ROL_11_OfficeHomeAddress>
        <xsl:value-of select="ROL_11_OfficeHomeAddress/text()" />
      </ns0:ROL_11_OfficeHomeAddress>
    </xsl:if>

Так что, если бы вы использовали <xsl:strip-space>, это означало бы, что элемент будет отображаться на <ROL_11_OfficeHomeAddress></ROL_11_OfficeHomeAddress> только с пробелами, если только вы не прошли карту, изменив ее обратно на <xsl:element>.

Что вы можете попробовать, так это использовать шаблон вызова, подобный приведенному ниже (nodeXfrm - это узел)

<xsl:template name="StripElement">
    <xsl:param name="nodeXfrm"></xsl:param>
    <xsl:variable name="nodeName">
        <xsl:value-of select="local-name($nodeXfrm)"></xsl:value-of>
    </xsl:variable>
    <xsl:element name="{$nodeName}">
        <xsl:if test="normalize-space($nodeXfrm)!=''">
            <xsl:value-of select="$nodeXfrm/text()"/>
        </xsl:if>
    </xsl:element>
</xsl:template>

И тогда на вашей карте вы можете вызвать шаблон для каждого элемента, который вам нужно удалить таким образом

  <xsl:call-template name="StripElement">
    <xsl:with-param name="nodeXfrm" select="ROL_11_OfficeHomeAddress"></xsl:with-param>
  </xsl:call-template>

Гуру XSLT мог бы сделать это более элегантно

...