【问题标题】:IIB output XML with multiple root nodes具有多个根节点的 IIB 输出 XML
【发布时间】:2020-03-31 06:52:53
【问题描述】:

问题

给定一个接收多个 XML 消息的 MQ 输入,我想输出相同的消息,但分批成(比如说)3 组。

例如输入(其中每一行是输入队列中的一条新消息):

<In1/>
<In2><In2a/></In2>
<In3/>
<In4/>
<In5 test="test"/>
<In6/>

例如输出(其中每一行是输出队列上的一条新消息):

<In1/><In2><In2a/></In2><In3/>
<In4/><In5 test="test"/><In6/>

这样做的原因是为了将消息批量传输,以减少发送多条小消息的开销。

我尝试过的

我查看了this article,这表明使用内置集合节点可能是这种简单场景的一种选择。

我尝试创建 MQInput -> Collector -> MQOutput,但 Collector node 创建了一个特殊的 MessageCollection 对象,这不是我想要的。

然后我想,好吧,收集器将消息放在一起 - 现在我只需要使用 ESQL 创建一条新消息 - 但我似乎无法弄清楚 ESQL 来做这件事。

我目前的尝试:

DECLARE collection REFERENCE TO InputRoot.Collection;
MOVE collection FIRSTCHILD NAME 'MessagesIn';

DECLARE I INTEGER 1;
CREATE LASTCHILD OF OutputRoot.XMLNSC TYPE Name NAME 'Test';
WHILE LASTMOVE(collection) DO
    SET OutputRoot.XMLNSC.Test.*[I] = collection.XMLNSC.*[>];           
    MOVE collection NEXTSIBLING;
    SET I = I + 1;
END WHILE;
    
RETURN TRUE;

虽然这可行,但它这样做只是因为它创建了单个根“测试”,而我希望我的输出有效地具有多个根。

但是如果我删除 Test 文件夹,则会引发有关输出格式的错误,如下所示:

( ['GENERICROOT' : 0x3a6d0bc8]
  (0x01000000:Name  ):Properties = ( ['MQPROPERTYPARSER' : 0x422a14d8]
    (0x03000000:NameValue):MessageSet             = NULL
    (0x03000000:NameValue):MessageType            = NULL
    (0x03000000:NameValue):MessageFormat          = NULL
    (0x03000000:NameValue):Encoding               = NULL
    (0x03000000:NameValue):CodedCharSetId         = NULL
    (0x03000000:NameValue):Transactional          = NULL
    (0x03000000:NameValue):Persistence            = NULL
    (0x03000000:NameValue):CreationTime           = NULL
    (0x03000000:NameValue):ExpirationTime         = NULL
    (0x03000000:NameValue):Priority               = NULL
    (0x03000000:NameValue):ReplyIdentifier        = NULL
    (0x03000000:NameValue):ReplyProtocol          = 'UNKNOWN' (CHARACTER)
    (0x03000000:NameValue):Topic                  = NULL
    (0x03000000:NameValue):ContentType            = NULL
    (0x03000000:NameValue):IdentitySourceType     = NULL
    (0x03000000:NameValue):IdentitySourceToken    = NULL
    (0x03000000:NameValue):IdentitySourcePassword = NULL
    (0x03000000:NameValue):IdentitySourceIssuedBy = NULL
    (0x03000000:NameValue):IdentityMappedType     = NULL
    (0x03000000:NameValue):IdentityMappedToken    = NULL
    (0x03000000:NameValue):IdentityMappedPassword = NULL
    (0x03000000:NameValue):IdentityMappedIssuedBy = NULL
  )
  (0x01000000:Folder):XMLNSC     = ( ['xmlnsc' : 0x31d412c8]
    (0x01000000:Folder):In1  = 
    (0x01000000:Folder):In2  = (
      (0x01000000:Folder):In2a = 
    )
    (0x01000000:Folder):In3  = 
  )
)

错误信息如下:

        (0x03000000:NameValue):Text            = 'XML Writing Errors have occurred' (CHARACTER)
        (0x01000000:Name     ):ParserException = (
          (0x03000000:NameValue):File     = 'F:\build\slot1\S900_P\src\MTI\MTIforBroker\GenXmlParser4\ImbXMLNSCWriter.cpp' (CHARACTER)
          (0x03000000:NameValue):Line     = 976 (INTEGER)
          (0x03000000:NameValue):Function = 'ImbXMLNSCWriter::writeMisc' (CHARACTER)
          (0x03000000:NameValue):Type     = '' (CHARACTER)
          (0x03000000:NameValue):Name     = '' (CHARACTER)
          (0x03000000:NameValue):Label    = '' (CHARACTER)
          (0x03000000:NameValue):Catalog  = 'BIPmsgs' (CHARACTER)
          (0x03000000:NameValue):Severity = 3 (INTEGER)
          (0x03000000:NameValue):Number   = 5016 (INTEGER)
          (0x03000000:NameValue):Text     = 'Unexpected XML type at this point in document.' (CHARACTER)
          (0x01000000:Name     ):Insert   = (
            (0x03000000:NameValue):Type = 5 (INTEGER)
            (0x03000000:NameValue):Text = 'In2' (CHARACTER)
          )
          (0x01000000:Name     ):Insert   = (
            (0x03000000:NameValue):Type = 5 (INTEGER)
            (0x03000000:NameValue):Text = 'folderType' (CHARACTER)
          )

问题

问题的部分是:

  1. 有没有更好的方法来聚合这些消息?
  2. 如果根据 XMLNSC 编写器,具有多个根元素是无效的,是否有其他解决方法?或许将其视为 BLOB 而不是 XML?

【问题讨论】:

  • 请问,您将如何使用 作为无效的 xml。可能是如果您考虑减少消息的数量,那么您可以为与 XML 相比为压缩格式的 3 条消息的每种组合生成固定宽度的有效负载或 JSON。同样,这是在不知道您减少消息数量的动机的情况下进行的。
  • 它用于网络传输(通过互联网),因此对消息进行批处理意味着我们不会每次都有协议头,这会使消息的大小增加一倍以上。实际上,我可能会分成 10 组而不是 3 组——显示的消息只是一个示例。我要求消息保留在 XML 中,因此我不能使用 JSON - 我仍在研究是否允许将消息包装在父根节点 &lt;messages&gt; 中;所以现在我被多个根源困住了。它被称为 XML 片段,而不是文档,对吧?
  • 在您的问题中,您已经知道如何用单个根“Test”进行包装,因此同样您可以将“Test”替换为“messages”......不是吗?
  • 是的,任何单根都可以——我的意思是我的要求是否允许;不是技术上是否可行

标签: xml ibm-integration-bus extended-sql


【解决方案1】:

这样做的原因是为了将消息批量传输,以减少发送多条小消息的开销。

为什么您认为发送多条小消息是个问题?您是否进行了性能测试来确认这一点?

如果根据 XMLNSC 编写器,具有多个根元素是无效的,还有其他方法吗?

XMLNSC 编写器尽量不编写无效的 XML 文档,因此它总是拒绝输出两个根标记。 单独使用 XMLNSC 编写器永远不会成功。

可以通过使用 ESQL ASBITSTREAM 函数预序列化 XML 文档来解决此限制。您需要自己使用 ESQL 字符串函数将它们连接起来。

但是,您假设您的 XML 文档将永远不会包含换行符。你不能确定这一点,我认为这是一件危险的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多