この関数を使用して、指定したエレメントのビット・ストリーム表現を取得します。
エレメントに関連付けられたパーサーは、このエレメントとそのすべての子エレメントを逐次化します。 結果は、呼び出し側によって割り振られたメモリーにコピーされます。 指定されたすべてのオプションがオリジナルのビット・ストリーム (例えば、MQInput ノードによって WebSphere® MQ キューから読み取られたビット・ストリーム) のオプションと一致しており、オリジナルのビット・ストリームを受け取った後でメッセージが変更されていない特殊なケースでは、このオリジナルのビット・ストリームは割り振られたメモリーにコピーされます。 この場合、パーサーは構文解析を行ってメッセージを再び逐次化する必要はありません。
このように、これらのプロパティーを判別するアルゴリズムは ESQL BITSTREAM 関数で使用されるものと実質的に同じです。
パーサーの中には、FolderBitStream という別のモードをサポートしているものもあります。このモードでは、指示されているフィールドがフォルダーを表していれば、どのようなサブツリーでも有効なビット・ストリームが生成されます。
CciSize cniElementAsBitstream(
int* returnCode,
CciElement* element,
const struct CciByteArray* value,
CciChar* messageType,
CciChar* messageSet,
CciChar* messageFormat,
int encoding,
int ccsid,
int options);
以下の例は、オプション・パラメーターを使用してメッセージ・ツリーのさまざまな部分のビット・ストリームを生成する方法を示しています。
MQMD
MQRFH2
<test><data><aaa>text</aaa></data></test>
ノードは以下の 3 つのメッセージを伝搬します。CciMessage* outMsg[3];
CciTerminal* terminalObject;
CciElement* bodyChild;
CciElement* inRootElement;
CciElement* inSourceElement[3];
CciElement* outRootElement;
CciElement* outBlobElement;
CciElement* outBody;
struct CciByteArray bitstream[3];
int bitstreamOptions[3];
int retvalue;
int rc = 0;
int loopCount;
CCI_EXCEPTION_ST exception_st = {CCI_EXCEPTION_ST_DEFAULT};
const CciChar* constBLOBParserName =
cciString("NONE",BIP_DEF_COMP_CCSID);
const CciChar* constBLOBElementName =
cciString("BLOB",BIP_DEF_COMP_CCSID);
const CciChar* constEmptyString =
cciString("",BIP_DEF_COMP_CCSID);
/*build up and propagate 3 output messages*/
/*first message has bit stream for input message body*/
/*second message has bit stream for input MQRFH2*/
/*third message has bit stream for sub element from input message*/
/* Get the root element of the input message */
inRootElement = cniRootElement(&rc, message);
/*CCI_CHECK_RC();*/
checkRC(rc);
/*set up the array of source elements and bitstream options*/
/*message body*/
inSourceElement[0] = cniLastChild(&rc,inRootElement);
checkRC(rc);
/*This is the root of the message body so we use RootBitStream mode*/
bitstreamOptions[0] = CCI_BITSTREAM_OPTIONS_ROOT;
/*last header*/
inSourceElement[1] = cniPreviousSibling(&rc,inSourceElement[0]);
checkRC(rc);
/*This is the root of the MQRFH2 so we use RootBitStream mode*/
bitstreamOptions[1] = CCI_BITSTREAM_OPTIONS_ROOT;
/*body.FIRST(first child of message body) */
inSourceElement[2] = cniFirstChild(&rc,inSourceElement[0]);
checkRC(rc);
/*body.FIRST.FIRST */
inSourceElement[2] = cniFirstChild(&rc,inSourceElement[2]);
checkRC(rc);
/*This is a sub tree within the message body so we use FolderBitStream mode*/
bitstreamOptions[2] = CCI_BITSTREAM_OPTIONS_FOLDER;
for (loopCount=0;loopCount<3;loopCount++) {
int bufLength;
/* Create new message for output */
outMsg[loopCount] = cniCreateMessage(&rc, cniGetMessageContext(&rc, message));
checkRC(rc);
/* Get the root element of the output message */
outRootElement = cniRootElement(&rc, outMsg[loopCount]);
checkRC(rc);
/* Copy the contents of the input message to the output message */
cniCopyElementTree(&rc, inRootElement, outRootElement);
checkRC(rc);
/* Get the last child of root (ie the body) */
bodyChild = cniLastChild(&rc, outRootElement);
checkRC(rc);
/*throw away the message body which was copied from the input message*/
cniDetach(&rc,
bodyChild);
checkRC(rc);
/*create the new output message body in the BLOB domain*/
outBody = cniCreateElementAsLastChildUsingParser(&rc,
outRootElement,
constBLOBParserName);
checkRC(rc);
/*create the BLOB element*/
outBlobElement = cniCreateElementAsLastChild(&rc,
outBody);
checkRC(rc);
cniSetElementName(&rc,
outBlobElement,
constBLOBElementName);
checkRC(rc);
/*Set the value of the blob element by obtaining the bit stream for the
element */
bitstream[loopCount].size=512;
bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * 512);
bufLength = cniElementAsBitstream(&rc,
inSourceElement[loopCount],
&bitstream[loopCount],
constEmptyString,/*assume XML message so no interest in*/
constEmptyString,/* type, set or format*/
constEmptyString,
0,/*Use Queue Manager CCSID & Encoding*/
0,
bitstreamOptions[loopCount]);
if (rc==CCI_BUFFER_TOO_SMALL)
{
free(bitstream[loopCount].pointer);
bitstream[loopCount].size=bufLength;
bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * bitstream[loopCount].size);
bufLength = cniElementAsBitstream(&rc,
inSourceElement[loopCount],
&bitstream[loopCount],
constEmptyString,/*assume XML message so no interest in*/
constEmptyString,/* type, set or format*/
constEmptyString,
0,/*Use Queue Manager CCSID & Encoding*/
0,
bitstreamOptions[loopCount]);
}
checkRC(rc);
bitstream[loopCount].size=bufLength;
cniSetElementByteArrayValue(&rc,
outBlobElement,
&bitstream[loopCount]);
checkRC(rc);
}
/* Get handle of output terminal */
terminalObject = getOutputTerminalHandle( (NODE_CONTEXT_ST *)context,
(CciChar*)constOut);
/* If the terminal exists and is attached, propagate to it */
if (terminalObject) {
if (cniIsTerminalAttached(&rc, terminalObject)) {
/* As this is a new, and changed message, it should be finalized... */
cniFinalize(&rc, outMsg[0], CCI_FINALIZE_NONE);
cniFinalize(&rc, outMsg[1], CCI_FINALIZE_NONE);
cniFinalize(&rc, outMsg[2], CCI_FINALIZE_NONE);
retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[0]);
retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[1]);
retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[2]);
if (retvalue == CCI_FAILURE) {
if (rc == CCI_EXCEPTION) {
/* Get details of the exception */
memset(&exception_st, 0, sizeof(exception_st));
cciGetLastExceptionData(&rc, &exception_st);
/* Any local error handling can go here */
/* Ensure message is deleted prior to return/throw */
cniDeleteMessage(0, outMsg[0]);
cniDeleteMessage(0, outMsg[1]);
cniDeleteMessage(0, outMsg[2]);
/* We must "rethrow" the exception; note this does not return */
cciRethrowLastException(&rc);
}
else {
/* Some other error...the plugin might choose to log it using the CciLog() */
/* utility function */
}
}
else {
}
}
}
else {
/* Terminal did not exist...severe internal error. The plugin might want to */
/* log an error here by using the cciLog() utility function. */
}
/* Delete the messages we created now we have finished with them */
cniDeleteMessage(0, outMsg[0]);
cniDeleteMessage(0, outMsg[1]);
cniDeleteMessage(0, outMsg[2]);
free((void*) constBLOBParserName);
free((void*) constBLOBElementName);
free((void*) constEmptyString);
return;