Невозможно создать повторяющиеся корневые узлы элемента XML с использованием XMLNS в IBM Integration Bus - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь создать ответ для моего мыльного веб-сервиса в шине интеграции IBM.Я использую вычислительный узел ESQL для генерации XML с использованием XMLNS.Я должен добавить некоторые повторяющиеся корневые узлы элемента в мой XML, и это то, с чем я столкнулся с проблемой.

DECLARE tnsp NAMESPACE '...';

SET OutputRoot.XMLNS.Response.(XML.NamespaceDecl)xmlns:acc = tnsp;
SET OutputRoot.XMLNS.Response.tnsp:ReqID = 'ID102';
SET OutputRoot.XMLNS.Response.tnsp:CompanyName = 'Example';

SET OutputRoot.XMLNS.Response.tnsp:Employee.tnsp:id = 'E100';
SET OutputRoot.XMLNS.Response.tnsp:Employee.tnsp:name = 'John';

Это дает

<Response xmlns:acc="...">
    <acc:ReqID>ID102</acc:ReqID>
    <acc:CompanyName>Example</acc:CompanyName>
    <acc:Employee>
        <acc:id>E100</acc:id>
        <acc:name>John</acc:name>
    </acc:Employee>
</Response>

Я хочу добавить больше сотрудниковузлы, такие как

<Response xmlns:acc="...">
    <acc:ReqID>ID102</acc:ReqID>
    <acc:CompanyName>Example</acc:CompanyName>
    <acc:Employee>
        <acc:id>E100</acc:id>
        <acc:name>John</acc:name>
    </acc:Employee>
    <acc:Employee>
        <acc:id>E101</acc:id>
        <acc:name>Alex</acc:name>
    </acc:Employee>
    .
    .
    .
</Response>

Как мне этого добиться?Я попытался повторить код для добавления узла сотрудника, но он заменяет существующий и выводит последнее обновленное.

Ответы [ 2 ]

0 голосов
/ 11 мая 2019

Другая альтернатива, и, как правило, предпочтительнее в отношении производительности, заключается в использовании CREATE и REFERENCE. Я создал простой тестовый поток.

enter image description here

Transform ComputeNode содержит следующий код.

BROKER SCHEMA com.nsd

CREATE COMPUTE MODULE Transform
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
    -- Declare the namespaces we want to use
    DECLARE acc NAMESPACE 'http://acc';    
    DECLARE soap NAMESPACE 'http://schemas.xmlsoap.org/soap/envelope/';

    -- Create the SOAP aggregate assigning the SOAP parser by using DOMAIN 'SOAP'
    CREATE LASTCHILD OF OutputRoot DOMAIN 'SOAP';

    -- By using the following statements to create elements in the SOAP.Context subtree
    -- our output will use namespace prefixes of soap and acc rather than NS1 and NS2
    SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:soap = soap;
    SET OutputRoot.SOAP.Context.Namespace.(SOAP.NamespaceDecl)xmlns:acc = acc;

    -- Create the main Response aggregate inside the SOAP.Body
    DECLARE ResponseRefOut REFERENCE TO OutputRoot;
    CREATE LASTCHILD OF OutputRoot.SOAP.Body AS ResponseRefOut NAMESPACE acc NAME 'Response';

    -- Add the non repeating aggregate field
    DECLARE EmployeeListRefIn REFERENCE TO InputRoot.SOAP.Body.employeeList;
    SET ResponseRefOut.acc:ReqID = 'ID' || EmployeeListRefIn.requestId;
    SET ResponseRefOut.acc:CompanyName = EmployeeListRefIn.company;

    -- Loop through the employee's in the input creating Employee aggregates in the output
    DECLARE EmployeeRefOut REFERENCE TO OutputRoot;
    DECLARE EmployeeRefIn REFERENCE TO EmployeeListRefIn.employee;
    WHILE LASTMOVE(EmployeeRefIn) DO
        CREATE LASTCHILD OF ResponseRefOut AS EmployeeRefOut NAMESPACE acc NAME 'Employee';

        SET EmployeeRefOut.acc:id = EmployeeRefIn.id;
        SET EmployeeRefOut.acc:name = EmployeeRefIn.firstName;

        MOVE EmployeeRefIn NEXTSIBLING REPEAT NAME;
    END WHILE;

    RETURN TRUE;
END;
END MODULE;

И следующие входные данные для проверки.

<?xml version="1.0"?>
<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header/>
    <soap:Body>
        <employeeList>
            <requestId>102</requestId>
            <company>Universal Happiness</company>
            <employee>
                <id>E100</id>
                <firstName>John</firstName>
            </employee>
            <employee>
                <id>E101</id>
                <firstName>Peter</firstName>
            </employee>
            <employee>
                <id>E102</id>
                <firstName>Paul</firstName>
            </employee>
        </employeeList>
    </soap:Body>
</soap:Envelope>

И это показывает, как выглядит конфигурация узла трассировки.

enter image description here

Создает следующий вывод.
Обратите внимание на три синтаксических анализатора, которые имеют форму [{ ParserName }: { ParserInstance }], которые были присоединены к дереву элементов. А именно SOAPRoot, MQPROPERTYPARSER и SOAP.

Trace showing the content of the response message

( ['SOAPRoot' : 0x1b633e9ff60]
  (0x01000000:Name  ):Properties = ( ['MQPROPERTYPARSER' : 0x1b406434d80]
    (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          = 'SOAP-AXIS2' (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):SOAP       = ( ['SOAP' : 0x1b62a218430]
    (0x01000000:Folder):Context = (
      (0x01000000:Folder):Namespace = (
        (0x03000102:NamespaceDecl)xmlns:soap = 'http://schemas.xmlsoap.org/soap/envelope/' (CHARACTER)
        (0x03000102:NamespaceDecl)xmlns:acc  = 'http://acc' (CHARACTER)
      )
    )
    (0x01000000:Folder):Body    = (
      (0x01000000:Folder)http://acc:Response = (
        (0x03000000:PCDataField)http://acc:ReqID       = 'ID102' (CHARACTER)
        (0x03000000:PCDataField)http://acc:CompanyName = 'Universal Happiness' (CHARACTER)
        (0x01000000:Folder     )http://acc:Employee    = (
          (0x03000000:PCDataField)http://acc:id   = 'E100' (CHARACTER)
          (0x03000000:PCDataField)http://acc:name = 'John' (CHARACTER)
        )
        (0x01000000:Folder     )http://acc:Employee    = (
          (0x03000000:PCDataField)http://acc:id   = 'E101' (CHARACTER)
          (0x03000000:PCDataField)http://acc:name = 'Peter' (CHARACTER)
        )
        (0x01000000:Folder     )http://acc:Employee    = (
          (0x03000000:PCDataField)http://acc:id   = 'E102' (CHARACTER)
          (0x03000000:PCDataField)http://acc:name = 'Paul' (CHARACTER)
        )
      )
    )
  )
)
0 голосов
/ 10 мая 2019

Этого можно добиться, превратив Employeenode в массив

SET OutputRoot.XMLNS.Response.tnsp:Employee[1].tnsp:id = 'E100';
...