BizTalk信封模式自闭节点

时间:2014-03-31 16:24:14

标签: xml biztalk biztalk-2013

我创建了一个BizTalk接收位置,它有一个订阅发送端口,接受封装消息,并使用XML接收管道分成单独的消息。

<?xml version="1.0" encoding="utf-8"?>
<MyEnvelope xmlns="MyNameSpace">
    <MyData>ABC</MyData>
    <MyData>DEF</MyData>
    <MyData>GHI</MyData>
</MyEnvelope>

保存为

<?xml version="1.0" encoding="utf-8"?>
<MyData xmlns="MyNameSpace">ABC</MyData>

 <?xml version="1.0" encoding="utf-8"?>
 <MyData xmlns="MyNameSpace">DEF</MyData>

 <?xml version="1.0" encoding="utf-8"?>
 <MyData xmlns="MyNameSpace">GHI</MyData>

这很棒。

但是,当邮件中没有元素时,服务会发送带有自闭和空信封的邮件:

<?xml version="1.0" encoding="utf-8"?>
<MyEnvelope xmlns="MyNameSpace"/>

我收到错误消息

  

来源:“XML反汇编程序”接收端口:“InLocation”URI:   “c:\ MyLocation * .xml”原因:状态中出现意外事件(“eos”)   “processing_header”。

如果我手动创建一个非自动关闭的消息:

<?xml version="1.0" encoding="utf-8"?>
<MyEnvelope xmlns="MyNameSpace"></MyEnvelope>

我没有错误。我的处理不受错误的影响,但必须对性能产生一些影响,并且群集中心暂停实例视图。

似乎BizTalk将自闭节点解释为空白而不是空。这似乎与my issues with attempting to call a service with no parameters有关,我需要发送一个自闭节点,但BizTalk只是不发送任何内容。

处理没有内容的信封一定是个常见问题。如何配置我的应用程序以使用自动关闭的信封节点来接收和忽略这些消息?

4 个答案:

答案 0 :(得分:3)

它们似乎经常改变白色空间的处理方式。见Change in Default Whitespace Behavior in BizTalk。我不确定您的问题是否相关,但值得一看。它没有提到BizTalk 2013但是主机中有设置。如果您执行此配置设置,则需要专门为其设置主机,以便它对其他现有应用程序(如果有)没有影响。

安装以下某个更新会导致BizTalk更改默认行为,以在映射期间保留XML中的空格:

  1. BizTalk 2010 CU1或以上
  2. BizTalk 2009 CU3或以上
  3. BizTalk 2006 R2 SP1 CU4或以上
  4. Hotfix 2492255
  5. 在某些环境中,转换可能最好删除空格。为了恢复此行为,可以执行以下步骤:

    在BizTalk 2010中,这是在主机级别设置的:

    1. 打开BizTalk Server管理控制台
    2. 将BizTalk组扩展到平台设置&gt;主机
    3. 右键单击主机,然后选择“设置”
    4. 选中Legacy whitespace behavior
    5. 旁边的复选框
    6. 点击确定
    7. 重新启动此主机的BizTalk主机实例
    8. 在BizTalk 2009和2006 R2中,此值设置为每台计算机级别:

      1. 打开注册表编辑器
      2. 在基于x86的计算机上找到并单击以下注册表子项: •HKEY_LOCAL_MACHINE \ Software \ Microsoft \ BizTalk Server \ 3.0 \ Administration 对于基于x64的计算机,请单击以下注册表子项: •HKEY_LOCAL_MACHINE \ Software \ Microsoft \ BizTalk Server \ 3.0 \ Administration
        •HKEY_LOCAL_MACHINE \ Software \ Wow6432Node \ Microsoft \ BizTalk Server \ 3.0 \ Administration
      3. 右键单击并选择“DWORD值”。
      4. 键入LegacyWhitespace作为值名称,然后双击它并将值数据设置为1.
      5. 退出注册表编辑器。
      6. 在此计算机上重新启动BizTalk主机实例

答案 1 :(得分:1)

我没有看到或验证过这种行为,但我会信任你;)。

除非您每小时获得10K文件或类似内容,否则不要担心例外情况的影响。

为防止出现错误,您必须在管道组件中撤消或重新格式化邮件。

答案 2 :(得分:1)

我知道这是一个老问题,但我遇到了同样的事情(特别是在返回空结果集的SQL XML轮询/过程中)。通常我会确保SQL不会被调用,如果它返回一个空的结果集(改进Data Available语句),但有时它不完全可能或万无一失。最后,我在解码阶段编写了一个自定义管道组件。它意味着要做到以下几点:

  1. 检查这是否是信封架构(此错误发生的唯一时间
  2. 尝试变得宽容,因为BizTalk的格式错误(至少在XML中的无效字符方面)
  3. 检查第一个内容元素(即根元素)是否为空
  4. 如果是,请使用&#34; FullEndElement&#34;。
  5. 重写
  6. 重置流并将其添加到资源跟踪器以进行最终处置
  7. 在一个例外情况下,静静地写入调试跟踪器,但只是让BizTalk从那里获取它 - 它最糟糕的是产生嘈杂但无害的错误消息。
  8. Stream origStream = pInMsg.BodyPart.GetOriginalDataStream();
    try
    {
        XmlReaderSettings readerSettings = new XmlReaderSettings();
        readerSettings.CheckCharacters = false; 
        readerSettings.CloseInput = false;
    
        XmlReader reader = XmlReader.Create(origStream, readerSettings);
        pContext.ResourceTracker.AddResource(reader);
    
        reader.MoveToContent();
    
        IDocumentSpec docSpec = pContext.GetDocumentSpecByType(reader.NamespaceURI + "#" + reader.LocalName);
        if (!string.IsNullOrWhiteSpace(docSpec.GetBodyPath()) && reader.IsEmptyElement) // this is an envelope schema with an empty root node
        {
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.CheckCharacters = false;
            writerSettings.OmitXmlDeclaration = true;
    
            MemoryStream ms = new MemoryStream(); // for such a small stream, MemoryStream is perfectly fine - normally use VirtualStream.
            pContext.ResourceTracker.AddResource(ms);
    
            XmlWriter writer = XmlWriter.Create(ms, writerSettings);
            pContext.ResourceTracker.AddResource(writer);
    
            writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
            writer.WriteFullEndElement();
            writer.Flush();
    
            ms.Position = 0;
            pInMsg.BodyPart.Data = ms;
        }
    }
    catch (Exception e)
    {
        // swallow exception 
        System.Diagnostics.Debug.WriteLine(e.ToString());
    }
    finally // make sure we're somewhat well behaved
    {
        if (pInMsg.BodyPart.Data.CanSeek == true)
            pInMsg.BodyPart.Data.Position = 0;
    }
    

答案 3 :(得分:0)

另一个(非常)迟来的答案。它并不能真正回答OP的问题,但是由于我是在这里搜索错误消息的,并且最终使我找到了此解决方案,所以我认为无论如何它都会对其他人有所帮助。

如果您像我一样可以控制信封的结构,则可以在信封中添加另一个级别,如果该级别是自动关闭的,则不会导致错误。

因此,这将导致错误:

<MyEnvelope xmlns="MyNameSpace" />

但这不会:

<MyEnvelope xmlns="MyNameSpace">
  <Body />
</MyEnvelope>

将架构的主体XPath设置为此嵌套级别,并且应该可以正常处理。

<MyEnvelope xmlns="MyNameSpace">
    <Body>
        <MyData>ABC</MyData>
        <MyData>DEF</MyData>
        <MyData>GHI</MyData>
    </Body>
</MyEnvelope>