【问题标题】:BizTalk HL7 send pipeline error due to line breaks in empty XML elements由于空 XML 元素中的换行符,BizTalk HL7 发送管道错误
【发布时间】:2012-02-21 10:10:13
【问题描述】:

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

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

元素“ROL_11_OfficeHomeAddress”的结构无效

如果我查看挂起的消息,我会明白为什么会发生这种情况。 ROL_11 元素为空,如下所示:

    <ROL_11_OfficeHomeAddress>
    </ROL_11_OfficeHomeAddress>

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

我可以将 XSLT 包装在 &lt;xsl:if&gt; 语句中,以便在编写 XML 之前检查值。然而,这个问题在很多地方都发生了,像这样包装每个元素似乎有点过头了。

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

<ROL_11_OfficeHomeAddress />

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

我已经尝试过的事情:

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

  • 更改地图的网格属性以将 Indent 设置为 No,希望删除空白。这对暂停消息中看到的 XML 没有影响。

  • 根据this guidance 添加用于旧版空白处理的注册表项。同样,这似乎根本没有效果。

【问题讨论】:

    标签: xslt biztalk biztalk-2009 hl7


    【解决方案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 可空元素映射中生成如下所示的 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>
    

    因此,如果您确实使用了&lt;xsl:strip-space&gt;,则意味着如果只有空格,该元素将映射到&lt;ROL_11_OfficeHomeAddress&gt;&lt;/ROL_11_OfficeHomeAddress&gt;,除非您通过映射将其更改回&lt;xsl:element&gt;

    您可以尝试使用如下调用模板(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 大师或许可以更优雅地做到这一点

    【讨论】:

    • 非常感谢您的回答;我没有想过将整个东西转换为 XSLT。我唯一的问题是,我仍然必须将&lt;xsl:if&gt; 测试添加到所有可能发生这种情况的地方。但是,如果我将整个映射转换为 XSLT,我可以使用&lt;xsl:strip-space&gt; 函数在全局范围内执行此操作吗?还是我误解了它的目的?
    【解决方案2】:

    我最近也遇到了这个问题,但在 BizTalk 2013 中。我们将所有内容移至自定义 XSLT 文件以映射我们的 HL7v2。升级到 2013 后,以前可以使用的 &lt;xsl:strip-space&gt; 突然失效了。

    这是因为 BizTalk 2013 现在使用 XslCompiledTransform 类而不是现在已过时的 XslTransform 类,并且它不允许 &lt;xsl:strip-space&gt;。所以我也面临着没有全局方法来去除空白。

    但是,经过多次搜索和摸索,我发现了一篇晦涩难懂的博客文章,其中包含一些对我的解决方案有用的东西:

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

    主机设置中的一个选项,用于使用旧版空格(至少到目前为止)。

    【讨论】:

    猜你喜欢
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多