Manejar mensajes XML grandes

Cuando se analiza una corriente de bits de entrada se crea un árbol lógico, la representación en árbol de un mensaje XML generalmente es más grande y, en algunos casos, mucho más grande que la corriente de bits correspondiente. Los motivos son los siguientes:
  • La adición de punteros que enlazan los objetos entre sí
  • La conversión de datos de caracteres a Unicode que puede doblar el tamaño
  • La inclusión de los nombres de campo que pueden ser implícitos en la corriente de bits
  • La presencia de datos de control asociados al funcionamiento del intermediario

La manipulación de un árbol de mensaje de gran tamaño puede requerir mucho almacenamiento. Si diseña un flujo de mensajes que maneja mensajes de gran tamaño compuestos de estructuras repetitivas, puede codificar sentencias ESQL que le ayuden a disminuir la carga de almacenamiento del intermediario. Estas sentencias permiten acceder al mensaje de forma aleatoria y secuencial, pero presuponga que no necesita acceder a todo el mensaje de una vez.

Estas sentencias ESQL hacen que el intermediario efectúe un análisis limitado del mensaje y guarde solamente esa parte del árbol de mensaje que refleje un registro individual del almacenamiento cada vez. Si el proceso requiere que retenga la información de registro a registro, por ejemplo, para calcular un precio total de una estructura de elementos repetitivos dentro de un orden, puede declarar, inicializar y mantener variables ESQL o puede guardar los valores en otra parte del árbol de mensaje, por ejemplo, en LocalEnvironment.

Esta técnica reduce la memoria que utiliza el intermediario a la necesaria para guardar las corrientes de bits de entrada y salida completas más la necesaria para los árboles de un solo registro y permite ahorrar memoria cuando se encuentra en el mensaje incluso un pequeño número de repeticiones. El intermediario utiliza el análisis parcial y la posibilidad de analizar partes especificadas del árbol de mensaje a y desde la parte correspondiente de la corriente de bits.

Para utilizar estas técnicas en el nodo Compute, aplique estas técnicas generales:
  • Copie el texto del mensaje de entrada como una corriente de bits en una carpeta especial del mensaje de salida. Esto crea una copia modificable del mensaje de entrada que no se analiza y que, por lo tanto, utiliza una cantidad mínima de memoria.
  • Evite inspeccionar el mensaje de entrada de ningún modo. De este modo, se evita analizar el mensaje.
  • Utilice un bucle y una variable de referencia para recorrer el mensaje de registro en registro. Para cada registro:
    • Utilice las transformaciones normales para crear un subárbol de salida en una segunda carpeta especial.
    • Utilice la función ASBITSTREAM para generar una corriente de bits para el subárbol de salida que se almacena en un elemento BitStream colocado en la posición del árbol correspondiente a la posición necesaria de la corriente de bits final.
    • Utilice la sentencia DELETE para suprimir tanto el árbol de mensaje del registro de entrada como el de salida cuando haya terminado de manipularlos.
    • Cuando haya procesado todos los registros, desasocie las carpetas especiales de modo que no aparezcan en la corriente de bits de salida.
Puede variar estas técnicas para que se adapten al proceso necesario para los mensajes. El ESQL siguiente proporciona una ejemplo de una implementación y es una modificación del ejemplo de ESQL contenido en Transformación de un mensaje XML complejo. Utiliza una sola sentencia SET con funciones SELECT anidadas para transformar un mensaje que contiene estructuras repetitivas anidadas.
-- Copiar la cabecera MQMD
  SET OutputRoot.MQMD = InputRoot.MQMD;

  -- Crear una carpeta especial en el mensaje de salida que contenga el árbol de entrada
  -- Nota : SourceMessageTree es el elemento raíz de un analizador XML
  CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' NAME 'SourceMessageTree';

  -- Copiar el mensaje de entrada en una carpeta especial del mensaje de salida
  -- Nota : Esta es una copia de raíz a raíz que, por lo tanto, no creará árboles
  SET OutputRoot.XML.Data.SourceMessageTree = InputRoot.XML;

  -- Crear una carpeta especial en el mensaje de salida que contenga el árbol de salida
  CREATE FIELD OutputRoot.XML.Data.TargetMessageTree;

  -- Preparar el bucle a través de los elementos adquiridos
  DECLARE sourceCursor REFERENCE TO OutputRoot.XML.Data.SourceMessageTree.Invoice;
  DECLARE targetCursor REFERENCE TO OutputRoot.XML.Data.TargetMessageTree;
  DECLARE resultCursor REFERENCE TO OutputRoot.XML.Data;
  DECLARE grandTotal   FLOAT     0.0e0;

  -- Crear un bloque que facilite el abandono del proceso
  ProcessInvoice: BEGIN
    -- Si no hay facturas (Invoices) en el mensaje de entrada, no hay nada que hacer
    IF NOT LASTMOVE(sourceCursor) THEN
      LEAVE ProcessInvoice;
    END IF;

    -- Crear un bucle por las facturas del árbol de origen
    InvoiceLoop : LOOP
      -- Inspeccionar la factura actual y crear una sentencia coincidente
      SET targetCursor.Statement =
        THE ( 
          SELECT
            'Monthly'                                    AS (XML.Attribute)Type,
            'Full'                                       AS (0x03000000)Style[1],
            I.Customer.FirstName                         AS Customer.Name,
            I.Customer.LastName                          AS Customer.Surname,
            I.Customer.Title                             AS Customer.Title,
            (SELECT 
              FIELDVALUE(II.Title)              AS Title,
              CAST(II.UnitPrice AS FLOAT) * 1.6 AS Cost,
              II.Quantity                       AS Qty
            FROM I.Purchases.Item[] AS II 
            WHERE II.UnitPrice > 0.0 ) AS Purchases.Article[],
            (SELECT
              SUM( CAST(II.UnitPrice AS FLOAT) * 
                   CAST(II.Quantity  AS FLOAT) *
                   1.6                          )
            FROM I.Purchases.Item[] AS II                      ) AS Amount,
            'Dollars'                                  AS Amount.(XML.Attribute)Currency
          FROM sourceCursor AS I
          WHERE I.Customer.LastName <> 'White'
        );

      -- Convertir la sentencia actual en una corriente de bits
      DECLARE StatementBitStream BLOB
        CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) AS BLOB);
                
      -- Si SELECT ha generado un resultado, esto es, si la cláusula WHERE no la
      -- filtrado, procesar la sentencia
      IF StatementBitStream IS NOT NULL THEN
        -- crear un campo que contenga la corriente de bits del árbol de resultados
        CREATE LASTCHILD OF resultCursor
          Type  XML.BitStream
          NAME  'StatementBitStream'
          VALUE StatementBitStream;

        -- Añadir el importe de la sentencia actual al total
        -- Tener en cuenta que cast es necesario debido al comportamiento del elemento de sintaxis XML
        SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT);
      END IF;

      -- Suprimir el árbol de sentencia real dejando solo la versión de la corriente de bits
      DELETE FIELD targetCursor.Statement;

      -- Pasar a la siguiente factura y suprimir la factura anterior y cualquier
      -- elemento de texto que se haya propagado con las facturas
      REPEAT
        MOVE sourceCursor NEXTSIBLING;
        DELETE PREVIOUSSIBLING OF sourceCursor;
      UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE)
      END REPEAT;

      -- Si no hay más facturas que procesar, abandonar el bucle
      IF NOT LASTMOVE(sourceCursor) THEN
        LEAVE InvoiceLoop;
      END IF;

    END LOOP InvoiceLoop;
  END ProcessInvoice;

  -- Suprimir las carpetas de origen y destino temporales
  DELETE FIELD OutputRoot.XML.Data.SourceMessageTree;
  DELETE FIELD OutputRoot.XML.Data.TargetMessageTree;

  -- Finalmente añadir el total
  SET resultCursor.GrandTotal = grandTotal;
Esto genera el siguiente mensaje de salida:
<Data>
 <Statement Type="Monthly" Style="Full">
  <Customer>
   <Name>Andrew</Name>
   <Surname>Smith</Surname>
   <Title>Mr</Title>
  </Customer>
  <Purchases>
   <Article>
    <Title>The XML Companion </Title>
    <Cost>4.472E+1</Cost>
    <Qty>2</Qty>
   </Article>
   <Article>
    <Title>A Complete Guide to DB2 Universal Database</Title>
    <Cost>6.872E+1</Cost>
    <Qty>1</Qty>
   </Article>
   <Article>
    <Title>JAVA 2 Developers Handbook</Title>
    <Cost>9.5984E+1</Cost>
    <Qty>1</Qty>
   </Article>
  </Purchases>
  <Amount Currency="Dollars">2.54144E+2</Amount>
 </Statement>
 <GrandTotal>2.54144E+2</GrandTotal>
</Data>
Conceptos relacionados
Visión general de flujos de mensajes
Visión general de ESQL
Tareas relacionadas
Diseñar un flujo de mensajes
Definir el contenido del flujo de mensajes
Gestión de archivos ESQL
Transformación de un mensaje XML complejo
Referencia relacionada
Nodo Compute
Sentencia DELETE
Función ASBITSTREAM
Mensaje de ejemplo
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 22/08/2006
ac16740_