The tree representation of a message is typically bigger than the input bit stream. Manipulating a large message tree can require much storage but you can code Java™ methods that help to reduce the storage load on the broker.
Manipulating a large message tree can require much storage. If you design a message flow that handles large messages that are made up of repeating structures, you can code Java methods that help to reduce the storage load on the broker. These methods support both random and sequential access to the message, but assume that you do not need access to the whole message at one time.
These Java methods cause the broker to complete limited parsing of the message, and to keep in storage at one time, only that part of the message tree that reflects a single record. If your processing requires you to retain information from record to record (for example, to calculate a total price from a repeating structure of items in an order), you can either declare, initialize, and maintain Java variables, or you can save values in another part of the message tree; for example, in the local environment.
This technique reduces the memory that is used by the broker to the memory that is needed to hold the full input and output bit streams, plus the memory that is needed for the message trees of just one record. This technique also provides memory savings when even a few repeats are encountered in the message. The broker uses partial parsing and the ability to parse specified parts of the message tree, to and from the corresponding part of the bit stream.
MbOutputTerminal.propagate(MbMessageAssembly, true)
This
process allows message tree resources and parsers to be recovered
and reused for the next output message iteration.You can vary these techniques to suit the processing that is required for your messages.
The following example Java code demonstrates how to parse a large input message with many repeating records, where each record is propagated as an individual output message.
<TestCase>
<Record><Field1>A</Field1><Field2>B</Field2><Field3>C</Field3><Field4>D</Field4><Field5>EA</Field5></Record>
<Record><Field1>A</Field1><Field2>B</Field2><Field3>C</Field3><Field4>D</Field4><Field5>EA</Field5></Record>
<Record><Field1>A</Field1><Field2>B</Field2><Field3>C</Field3><Field4>D</Field4><Field5>EA</Field5></Record>
<Record><Field1>A</Field1><Field2>B</Field2><Field3>C</Field3><Field4>D</Field4><Field5>EA</Field5></Record>
....
</TestCase>
//Make a modifiable MbMessage based on the input message passed in on the inAssembly.
MbMessage clonedInMessage = new MbMessage(inAssembly.getMessage());
//Now partially parse the cloned input message one record at a time.
MbElement inputRootElement = clonedInMessage.getRootElement();
MbElement inputPropertiesElement = inputRootElement.getFirstElementByPath("Properties");
MbElement inputMQMDElement = inputRootElement.getFirstElementByPath("MQMD");
MbElement inputXMLNSCElement = inputRootElement.getFirstElementByPath("XMLNSC");
MbElement inputXMLNSCRootTagElement = inputXMLNSCElement.getFirstChild(); //Move to the TestCase tag
MbElement currentInputRecord = inputXMLNSCRootTagElement.getFirstChild(); //Move to the Record tag
while(currentInputRecord != null)
{
// Create a new output message for the record that we are going to be propagate.
MbMessage outputMessage = new MbMessage();
MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly, outputMessage);
//Create new parsers folders in the output message.
MbElement outputRootElement = outputMessage.getRootElement();
MbElement outputPropertiesElement = outputRootElement.createElementAsLastChild(inputPropertiesElement.getParserClassName());
MbElement outputMQMDElement = outputRootElement.createElementAsLastChild(inputMQMDElement.getParserClassName());
MbElement outputXMLNSCElement = outputRootElement.createElementAsLastChild(inputXMLNSCElement.getParserClassName());
//Create the root tag in the output XMLNSC folder that will be used for this output record.
MbElement outputXMLNSCRootTag = outputXMLNSCElement.createElementAsLastChild(MbElement.TYPE_NAME, "TestCase", null);
//Create the record tag for this output message instance.
MbElement currentOutputRecord = outputXMLNSCRootTag.createElementAsLastChild(MbElement.TYPE_NAME, "Record", null);
//Copy the Properties Folder, MQMD header, and the current record.
outputPropertiesElement.copyElementTree(inputPropertiesElement);
outputMQMDElement.copyElementTree(inputMQMDElement);
currentOutputRecord.copyElementTree(currentInputRecord);
//Propagate this message, requesting that the output message assembly be cleared after propagation.
out.propagate(outAssembly, true);
//Note: You do not need to call clearMessage on outputMessage because it was cleared after the propagation.
//Take a reference to the current record so that it can be deleted.
MbElement previousInputRecord = currentInputRecord;
//Now move to the next input record ready for processing.
currentInputRecord = currentInputRecord.getNextSibling();
//Now that we have moved to the next sibling, delete the input record that has already been processed.
previousInputRecord.delete();
}
<Record>
<Field1>A</Field1>
<Field2>B</Field2>
<Field3>C</Field3>
<Field4>D</Field4>
<Field5>E</Field5>
</Record>