Выход IIB XML с несколькими root узлами - PullRequest
0 голосов
/ 30 марта 2020

Проблема

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

например, Input ( где каждая строка является новым сообщением в очереди ввода):

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

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

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

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

То, что я пробовал

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

Я пытался создать MQInput -> Collector -> MQOutput, но Collector узел создает специальный MessageCollection объект, который не совсем то, что я хочу.

Итак, я подумал, ОК, Collector объединяет сообщения - теперь мне просто нужно создать новое сообщение, используя E SQL - но я могу Кажется, что E SQL не может это сделать.

Моя текущая попытка:

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;

Хотя это работает, оно делает это только потому, что создает один root «Тест», в то время как я хочу, чтобы мои выходные данные имели несколько корней.

Но если я удаляю папку «Тест», это приводит к ошибкам в формате вывода, который выглядит следующим образом:

( ['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. Если наличие нескольких элементов root недопустимо в соответствии с модулем записи XMLNS C, есть ли другой способ обойти это? Рассматривайте это как BLOB, а не XML, может быть?

1 Ответ

2 голосов
/ 31 марта 2020

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

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

Если наличие нескольких элементов root недопустимо в соответствии с модулем записи XMLNS C, есть ли другой способ обойти это?

Модуль записи XMLNS C пытается не записывать недействительные XML документы, поэтому он всегда будет отказываться выводить два тега root. Вам никогда не удастся использовать XMLNS C Writer отдельно .

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

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

...