Handhabung umfangreicher XML-Nachrichten

Bei der Syntaxanalyse eines Eingabebitstroms und der Erstellung einer logischen Baumstruktur ist die Darstellung der Baumstruktur einer XML-Nachricht für gewöhnlich umfangreicher (in einigen Fällen viel umfangreicher) als der entsprechende Bitstrom. Zu den Gründen zählen folgende:
  • Die Addierung der Zeiger, mit denen die Objekte miteinander verknüpft werden
  • Die Umsetzung der Zeichendaten in Unicode; dies kann zu einer Verdoppelung der Größe führen
  • Die Aufnahme von Feldnamen, die im Bitstrom möglicherweise implizit waren
  • Die Existenz von Steuerdaten, die der Brokeroperation zugeordnet sind

Bei der Bearbeitung einer umfangreichen Nachrichtenbaumstruktur kann ein hoher Bedarf an Speicherplatz entstehen. Wenn Sie einen Nachrichtenfluss entwerfen, der umfangreiche Nachrichten verarbeitet, die aus sich wiederholenden Strukturen bestehen, können Sie 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 lediglich 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 teilweise Syntaxanalyse und die Möglichkeit, angegebene Bereiche der Nachrichtenbaumstruktur in und aus dem entsprechenden Bereich des Bitstroms syntaktisch zu analysieren.

Zur Anwendung dieser Verfahren in Ihrem Rechenknoten müssen Sie die folgenden allgemeinen Verfahren einsetzen:
  • Kopieren Sie den Hauptteil der Eingabenachricht als Bitstrom in einen speziellen Ordner in der Ausgabenachricht. Auf diese Weise wird eine modifizierbare Kopie der Eingabenachricht erstellt, die nicht syntaktisch analysiert wird und daher nur einen geringen Speicherplatzbedarf hat.
  • Vermeiden Sie die Überprüfung der Eingabenachricht. Auf diese Weise wird die Notwendigkeit umgangen, die Nachricht syntaktisch zu analysieren.
  • Verwenden Sie eine Schleife und eine Referenzvariable, um jeweils einen Datensatz nach dem anderen in der Nachricht zu bearbeiten. Für jeden Datensatz gilt Folgendes:
    • Erstellen Sie mit Hilfe normaler Umsetzungen in einem zweiten speziellen Ordner eine entsprechende untergeordnete Ausgabebaumstruktur.
    • Generieren Sie mit Hilfe der Funktion ASBITSTREAM einen Bitstrom für die untergeordnete Ausgabebaumstruktur, der im Element 'BitStream' gespeichert wird, das in der Baumstruktur an die Stelle gesetzt wird, die ihrer erforderlichen Position im endgültigen Bitstrom entspricht.
    • Löschen Sie mit Hilfe der Anweisung DELETE die aktuellen Nachrichtenbaumstrukturen sowohl für die Ein- als auch die Ausgabedatensätze, wenn Sie ihre Bearbeitung abgeschlossen haben.
    • Sobald Sie die Verarbeitung aller Datensätze abgeschlossen haben, hängen Sie die speziellen Ordner ab, damit diese nicht im Ausgabebitstrom angezeigt werden.
Sie können diese Verfahren variieren und so an die Verarbeitung anpassen, die für Ihre Nachrichten erforderlich ist. Der unten genannte ESQL-Code ist ein Beispiel einer Implementierung. Er basiert auf dem Beispiel im Abschnitt Komplexe XML-Nachricht umwandeln und wurde entsprechend umgeschrieben. In diesem Code wird eine einzelne SET-Anweisung mit verschachtelten SELECT-Funktionen verwendet, um eine Nachricht umzuwandeln, die verschachtelte, sich wiederholende Strukturen aufweist.
-- Copy the MQMD header
  SET OutputRoot.MQMD = InputRoot.MQMD;

  -- Create a special folder in the output message to hold the input tree
  -- Note : SourceMessageTree is the root element of an XML parser
  CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' 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.XML.Data.SourceMessageTree = InputRoot.XML;

  -- Create a special folder in the output message to hold the output tree
  CREATE FIELD OutputRoot.XML.Data.TargetMessageTree;

  -- Prepare to loop through the purchased items
  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;

  -- 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 (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'
        );

      -- Turn the current Statement into a bit stream
      DECLARE StatementBitStream BLOB
        CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) AS BLOB);
                
      -- 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
        CREATE LASTCHILD OF resultCursor
          Type  XML.BitStream
          NAME  'StatementBitStream'
          VALUE StatementBitStream;

        -- Add the current Statement's Amount to the grand total
        -- Note that the cast is necessary because of the behavior of the XML syntax element
        SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT);
      		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.XML.Data.SourceMessageTree;
  DELETE FIELD OutputRoot.XML.Data.TargetMessageTree;

  -- Finally add the grand total
  SET resultCursor.GrandTotal = grandTotal;
Dies führt zur Generierung der folgenden Ausgabenachricht:
<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>
Zugehörige Konzepte
Nachrichtenflüsse - Übersicht
Übersicht zu ESQL
Zugehörige Tasks
Einen Nachrichtenfluss entwerfen
Nachrichtenflussinhalte definieren
ESQL-Dateien verwalten
Komplexe XML-Nachricht umwandeln
Zugehörige Verweise
Rechenknoten (Compute)
DELETE-Anweisung
ASBITSTREAM-Funktion
Beispielnachricht
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 23. Aug. 2006
ac16740_