IIB выводит XML с несколькими корневыми узлами

Проблема

Учитывая вход MQ, который получает несколько сообщений XML, я хочу вывести те же сообщения, но сгруппированные в группы (скажем) по 3.

например Ввод (где каждая строка - это новое сообщение во входной очереди):

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

например Вывод (где каждая строка - это новое сообщение в очереди вывода):

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

Причина этого заключается в том, чтобы пакетировать сообщения для передачи, чтобы уменьшить накладные расходы на отправку нескольких небольших сообщений.

Что я пробовал

Я просмотрел эту статью, в которой предлагается что использование встроенных узлов сбора может быть вариантом для такого простого сценария.

Я пробовал создать MQInput - ›Collector -› MQOutput, но Узел сборщика создает специальный 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?

person simonalexander2005    schedule 30.03.2020    source источник
comment
Могу я спросить, как вы собираетесь использовать ‹In1 /› ‹In2› ‹In2a /› ‹/In2› ‹In3 /› как недопустимый xml. Может быть, если вы хотите уменьшить количество сообщений, вы можете сгенерировать полезную нагрузку фиксированной ширины или JSON для каждой комбинации из 3 сообщений, которые являются сжатыми форматами по сравнению с XML. Опять же, это без знания вашей мотивации к сокращению количества сообщений.   -  person Rohan    schedule 01.04.2020
comment
Это для передачи по сети (через Интернет), поэтому пакетирование сообщений означает, что у нас не будет заголовка протокола каждый раз, что более чем вдвое увеличивает размер сообщений. На самом деле я бы, вероятно, разделил их на группы по 10, а не по 3 - показанные сообщения являются лишь примером. У меня есть требование, чтобы сообщения оставались в XML, поэтому я не могу использовать JSON - я все еще смотрю, разрешено ли мне переносить сообщения в родительский корневой узел <messages> или нет; так что пока я застрял с несколькими корнями. Он известен как XML-фрагмент, а не как документ, верно?   -  person simonalexander2005    schedule 02.04.2020
comment
В вашем вопросе вы выяснили, как обернуть тест с одним корневым элементом, поэтому вы можете заменить тест сообщениями… не так ли?   -  person Rohan    schedule 02.04.2020
comment
да, подойдет любой корень - я имею в виду, разрешено ли это в моих требованиях; не то, возможно ли это технически   -  person simonalexander2005    schedule 02.04.2020


Ответы (1)


Причина этого заключается в том, чтобы пакетировать сообщения для передачи, чтобы уменьшить накладные расходы на отправку нескольких небольших сообщений.

Почему вы считаете, что отправка нескольких небольших сообщений является проблемой? Вы проводили тесты производительности, чтобы подтвердить это?

Если наличие нескольких корневых элементов недопустимо по мнению автора XMLNSC, есть ли другой способ обойти это?

Модуль записи XMLNSC старается не записывать недопустимые XML-документы, поэтому он всегда отказывается выводить два корневых тега. Вам никогда не удастся использовать средство записи XMLNSC в одиночку.

Вы можете обойти это ограничение, используя функцию ESQL ASBITSTREAM для предварительной сериализации XML-документов. Вам нужно будет объединить их самостоятельно, используя строковые функции ESQL.

Однако вы делаете предположение, что ваши XML-документы никогда, никогда не будут содержать перевода строки. Вы не можете быть уверены в этом, и я думаю, что это опасно.

person kimbert    schedule 30.03.2020