Bei der Syntaxanalyse eines Eingabebitstroms und der Erstellung einer logischen Baumstruktur ist die Darstellung der Baumstruktur einer MRM-Nachricht für gewöhnlich umfangreicher (in einigen Fällen viel umfangreicher) als der entsprechende Bitstrom.
Die Bearbeitung einer umfangreichen Nachrichtenbaumstruktur kann daher viel Speicherplatz in Anspruch nehmen. Wenn Sie einen Nachrichtenfluss entwerfen, der umfangreiche Nachrichten verarbeitet, die aus sich wiederholenden Strukturen bestehen, können Sie spezifische ESQL-Anweisungen codieren, die zu einer Reduzierung der Speicherbelastung im Broker führen. Diese Anweisungen unterstützen sowohl den wahlfreien als auch den sequenziellen Zugriff auf die Nachricht. Es wird jedoch vorausgesetzt, dass Sie nicht gleichzeitig auf die gesamte Nachricht zugreifen müssen.
Diese ESQL-Anweisungen veranlassen den Broker zur Ausführung einer eingeschränkten Syntaxanalyse der Nachricht. Außerdem speichert der Broker immer nur den Teil der Nachrichtenbaumstruktur, der einen einzelnen Datensatz reflektiert. Wenn in Ihrer Verarbeitung Informationen von Datensatz zu Datensatz beibehalten werden müssen (um beispielsweise den Gesamtpreis auf Grundlage einer sich wiederholenden Artikelstruktur in einer Bestellung auszurechnen), können Sie ESQL-Variablen entweder deklarieren, initialisieren und verwalten oder Werte in einem anderen Teil der Nachrichtenbaumstruktur (z. B. in der lokalen Umgebung) speichern.
Bei diesem Verfahren wird der vom Broker verwendete Speicher auf den Bedarf reduziert, der für das Speichern der vollständigen Ein- und Ausgabebitströme erforderlich ist, plus dem Speicherplatz, der für die Baumstrukturen eines Datensatzes benötigt wird. Dadurch wird selbst dann Speicherplatz gespart, wenn die Nachricht eine geringe Anzahl an Wiederholungen enthält. Der Broker nutzt die Teilsyntaxanalyse und die Möglichkeit, angegebene Bereiche der Nachrichtenbaumstruktur in und aus dem entsprechenden Bereich des Bitstroms syntaktisch zu analysieren.
Sie können diese Verfahren variieren und so an die Verarbeitung anpassen, die für Ihre Nachrichten erforderlich ist. Der folgende ESQL-Code ist ein Beispiel einer Implementierung.
Der ESQL-Code hängt von einer Nachricht namens LargeMessageExample ab, die zur Definition sowohl des Invoice-Eingabeformats als auch des Statement-Ausgabeformats erstellt wurde. Eine Nachricht namens AllInvoices wurde erstellt. Diese enthält ein globales Element namens Invoice, das sich einmal oder mehrmals wiederholen kann, sowie eine Nachricht namens Data, die ein globales Element namens Statement enthält, das sich einmal oder mehrmals wiederholen kann.
Den Definitionen der Elemente und Attribute wurden die richtigen Datentypen zugeordnet. Aus diesem Grund sind die CAST-Anweisungen, die vom ESQL-Code im XML-Beispiel verwendet wurden, nicht erforderlich. In der Nachrichtengruppe wurde ein physisches XML-Format namens XML1 erstellt, das eine Syntaxanalyse einer XML-Nachricht, die diesen Nachrichten entspricht, durch den MRM ermöglicht.
Wenn die Baumstruktur Anweisung mithilfe der Funktion ASBITSTREAM serialisiert wurde, werden Nachrichtengruppe, Nachrichtenart und Nachrichtenformat als Parameter angegeben. Der Parameter Nachrichtenart enthält den Pfad von der Nachricht zum Element, das serialisiert wird. In diesem Fall ist dies Data/Statement, da das Element Statement ein direktes untergeordnetes Element der Nachricht Data ist.
<AllInvoices> .... </AllInvoices>
CREATE COMPUTE MODULE LargeMessageExampleFlow_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
-- Create a special folder in the output message to hold the input tree
-- Note : SourceMessageTree is the root element of an MRM parser
CREATE LASTCHILD OF OutputRoot.MRM DOMAIN 'MRM' NAME 'SourceMessageTree';
-- Copy the input message to a special folder in the output message
-- Note : This is a root to root copy which will therefore not build trees
SET OutputRoot.MRM.SourceMessageTree = InputRoot.MRM;
-- Create a special folder in the output message to hold the output tree
CREATE FIELD OutputRoot.MRM.TargetMessageTree;
-- Prepare to loop through the purchased items
DECLARE sourceCursor REFERENCE TO OutputRoot.MRM.SourceMessageTree.Invoice;
DECLARE targetCursor REFERENCE TO OutputRoot.MRM.TargetMessageTree;
DECLARE resultCursor REFERENCE TO OutputRoot.MRM;
DECLARE grandTotal FLOAT 0.0e0;
-- Create a block so that it's easy to abandon processing
ProcessInvoice: BEGIN
-- If there are no Invoices in the input message, there is nothing to do
IF NOT LASTMOVE(sourceCursor) THEN
LEAVE ProcessInvoice;
END IF;
-- Loop through the invoices in the source tree
InvoiceLoop : LOOP
-- Inspect the current invoice and create a matching Statement
SET targetCursor.Statement =
THE (
SELECT 'Monthly' AS Type,
'Full' AS Style,
I.Customer.FirstName AS Customer.Name,
I.Customer.LastName AS Customer.Surname,
I.Customer.Title AS Customer.Title,
(SELECT
FIELDVALUE(II.Title) AS Title,
II.UnitPrice * 1.6 AS Cost,
II.Quantity AS Qty
FROM I.Purchases.Item[] AS II
WHERE II.UnitPrice > 0.0 ) AS Purchases.Article[],
(SELECT
SUM( II.UnitPrice *
II.Quantity *
1.6 )
FROM I.Purchases.Item[] AS II ) AS Amount,
'Dollars' AS Amount.Currency
FROM sourceCursor AS I
WHERE I.Customer.LastName <> 'White'
);
-- Turn the current Statement into a bit stream
-- The SET parameter is set to the name of the message set
-- containing the MRM definition
-- The TYPE parameter contains the path from the from the message
-- to element being serialized
-- The FORMAT parameter contains the name of the physical format
-- name defined in the message
DECLARE StatementBitStream BLOB
ASBITSTREAM(targetCursor.Statement
OPTIONS FolderBitStream
SET 'LargeMessageExample'
TYPE 'Data/Statement'
FORMAT 'XML1');
-- If the SELECT produced a result (that is, it was not filtered
-- out by the WHERE clause), process the Statement
IF StatementBitStream IS NOT NULL THEN
-- create a field to hold the bit stream in the result tree
-- The Type of the element is set to MRM.BitStream to indicate
-- to the MRM Parser that this is a bitstream
CREATE LASTCHILD OF resultCursor
Type MRM.BitStream
NAME 'Statement'
VALUE StatementBitStream;
-- Add the current Statement's Amount to the grand total
SET grandTotal = grandTotal + targetCursor.Statement.Amount;
END IF;
-- Delete the real Statement tree leaving only the bit stream version
DELETE FIELD targetCursor.Statement;
-- Step onto the next Invoice, removing the previous invoice and any
-- text elements that might have been interspersed with the Invoices
REPEAT
MOVE sourceCursor NEXTSIBLING;
DELETE PREVIOUSSIBLING OF sourceCursor;
UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE)
END REPEAT;
-- If there are no more invoices to process, abandon the loop
IF NOT LASTMOVE(sourceCursor) THEN
LEAVE InvoiceLoop;
END IF;
END LOOP InvoiceLoop;
END ProcessInvoice;
-- Remove the temporary source and target folders
DELETE FIELD OutputRoot.MRM.SourceMessageTree;
DELETE FIELD OutputRoot.MRM.TargetMessageTree;
-- Finally add the grand total
SET resultCursor.GrandTotal = grandTotal;
-- Set the output MessageType property to be 'Data'
SET OutputRoot.Properties.MessageType = 'Data';
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
END MODULE;