La representación en árbol de un mensaje XML generalmente es más grande que la corriente de bits de entrada. La manipulación de un árbol de mensaje grande puede requerir una gran cantidad de almacenamiento, pero puede codificar sentencias ESQL que ayuden a reducir la carga de almacenamiento en el intermediario.
La manipulación de un árbol de mensaje grande puede requerir mucho almacenamiento. Si diseña un flujo de mensajes que maneja mensajes grandes que están compuestos de estructuras repetitivas, puede codificar sentencias ESQL que ayuden a reducir la carga de almacenamiento en el intermediario. Estas sentencias permiten acceder al mensaje de forma aleatoria y secuencial, pero presuponen 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 en almacenamiento de una vez, solamente esa parte del árbol de mensaje que refleje un registro individual. Si el proceso requiere que se retenga la información registro a registro (por ejemplo, para calcular un precio total de una estructura repetitiva de elementos de un pedido) puede declarar, inicializar y mantener variables ESQL o puede guardar los valores en otra parte del árbol de mensaje; por ejemplo; en el entorno local.
Esta técnica reduce la memoria que el intermediario utiliza a la necesaria para contener las secuencias de bits de entrada y de salida completas, más la memoria que es necesaria para los árboles de mensajes de un solo registro. Esta técnica también proporciona un ahorro de memoria incluso cuando se encuentra un pequeño número de repeticiones en el mensaje. 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.
Puede variar estas técnicas para adaptarlas al proceso necesario para los mensajes.
-- 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.XMLNS.Data DOMAIN 'XMLNS' 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.XMLNS.Data.SourceMessageTree = InputRoot.XMLNS;
-- Crear una carpeta especial en el mensaje de salida que contenga el árbol de salida
CREATE FIELD OutputRoot.XMLNS.Data.TargetMessageTree;
-- Preparar el bucle a través de los elementos adquiridos
DECLARE sourceCursor REFERENCE TO OutputRoot.XMLNS.Data.SourceMessageTree.Invoice;
DECLARE targetCursor REFERENCE TO OutputRoot.XMLNS.Data.TargetMessageTree;
DECLARE resultCursor REFERENCE TO OutputRoot.XMLNS.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
ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream);
-- Si SELECT ha generado un resultado
-- (es decir, la cláusula WHERE no la ha 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 la 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;
-- Ir hasta el siguiente elemento Invoice,
-- eliminando la factura anterior y los
-- elementos de texto que pudieran haberse
-- entremezclado con las facturas (Invoices)
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.XMLNS.Data.SourceMessageTree;
DELETE FIELD OutputRoot.XMLNS.Data.TargetMessageTree;
-- Finalmente añadir el total
SET resultCursor.GrandTotal = grandTotal;
<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>