BizTalk HL7由于空XML元素中的换行而发送管道错误

时间:2012-02-21 10:10:13

标签: xslt biztalk biztalk-2009 hl7

我使用BizTalk映射器映射到HL7 A31消息。该地图有几个内联XSLT脚本functoid。

当XML通过HL7发送管道时,它会生成错误:

  

元素'ROL_11_OfficeHomeAddress'具有无效结构

如果我查看暂停的消息,我可以看到为什么会发生这种情况。 ROL_11元素为空,如下所示:

    <ROL_11_OfficeHomeAddress>
    </ROL_11_OfficeHomeAddress>

在开始和结束标记之间,由于缩进,有一个换行符和几个空格/制表符。这完全是由XSLT生成的,我相信它是导致错误的换行符。

我可以在编写XML之前将XSLT包装在<xsl:if>语句中以检查值。然而,在许多地方都出现了这个问题,并且像这样包装每一个元素似乎有点过分了。

我真正想要的是BizTalk自动将元素转换为空元素,如下所示:

<ROL_11_OfficeHomeAddress />

我相信这可以解决问题。我有什么方法可以告诉它这样做吗?

我已经尝试过的事情:

  • 使用<xsl:strip-space>但引发了自己的错误。我认为这是因为BizTalk将内联XSLT包装在自己的代码中,因此在错误的位置指定了条带空间。

  • 更改地图的网格属性,将缩进设置为,希望删除空格。这对挂起的消息中看到的XML没有影响。

  • 根据this guidance为旧式空白处理添加注册表项。再次,这似乎完全没有效果。

2 个答案:

答案 0 :(得分:1)

如果您转换entire map into 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通常在典型的1:1 nillable元素映射

中生成如下所示的XSLT
    <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专家可能能够更优雅地完成这项工作

答案 1 :(得分:1)

我最近也遇到了这个问题,但在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

主机设置中的一个选项,用于使用传统空白为我们做到了(至少到目前为止)。