获取指定元素的位流表示。与元素关联的解析器序列化元素及其所有子代。结果复制到调用者分配的内存。在指定的所有选项与原始位流的选项相 匹配的特殊情况下(例如,位流通过 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 RFH2 <test><data><stuff>things</stuff></data></test>节点将传播 3 个消息,一个消息将输入消息的副本包含在 BLOB 域中。另一个消息将输入 RFH2 的副本作为消息体包含在 BLOB 域中。第三个消息将 <data></data> 文件夹作为消息体包含在 BLOB 域中。
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 RFH2*/ /*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 RFH2 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, destinationList, exceptionList, outMsg[0]); retvalue = cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg[1]); retvalue = cniPropagate(&rc, terminalObject, destinationList, 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 may 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 may wish to */ /* log an error here 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;