在许多情况下,用户定义的节点需要访问在它的输入终端上接收到的消息的内容。消息由语法元素的树表示。提供了实用程序函数组以用于消息管理、消息缓冲区访问、语法元素导航和语法元素访问。(请参阅 C 节点实用程序函数,获取有关实用程序函数的详细信息。)
例如,要查询主体的第一个子的名称和类型:
void cniEvaluate( ... ){ ... /* Navigate to the target element */ rootElement = cniRootElement(&rc, message); bodyElement = cniLastChild(&rc, rootElement); bodyFirstChild = cniFirstChild(&rc, bodyElement); /* Query the name and value of the target element */ cniElementName(&rc, bodyFirstChild, (CciChar*)&elementname, sizeof(elementName)); bytes = cniElementCharacterValue( &rc, bodyfirstChild, (CciChar*)&eValue, sizeof(eValue)); ... }
要访问元素树的位流表示,您可以使用 cniElementAsBitstream函数。使用此函数,您可以获得消息中任何元素的位流表示。请参阅 cniElementAsBitstream,获取有关如何使用此函数和样本代码的详细信息。
接收到的输入消息是只读的,因此在消息可被转换之前,您必须使用 cniCreateMessage 函数将它写到新的输出消息。您从输入消息复制元素,或者您可以创建新的元素并将它们连接到消息。新的元素通常在解析器的域中。
{ ... context = cniGetMessageContext(&rc, message)); outMsg = cniCreateMessage(&rc, context)); ... }
cniCopyElementTree(&rc, sourceElement, targetElement);
cniSetElementIntegerValue(&rc, targetElement, L"newValue", 8);
cniDeleteMessage(&rc, outMsg);
cniCreateElementAsFirstChildUsingParsercniCreateElementAsLastChildUsingParser cniCreateElementAfterUsingParser cniCreateElementBeforeUsingParser应该使用这些函数,因为它们是专门用于将解析器分配给消息树文件夹的。
cniCreateElementAsFirstChildcniCreateElementAsLastChildcniCreateElementAfter cniCreateElementBefore
节点可以使用 Compute 节点 ESQL 语法调用 ESQL 表达式。您可以使用 ESQL 表达式创建和修改消息的组件,并且您可以使用 cniSqlCreateStatement、cniSqlSelect、cniSqlDeleteStatement 和 cniSqlExecute 函数,引用来自外部数据库的输入消息和数据的元素。
例如,要从数据库表中的列的内容植入 Result 元素:
{ ... sqlExpr = cniSqlCreateStatement(&rc, (NODE_CONTEXT_ST *)context->nodeObject, L"DB", CCI_SQL_TRANSACTION_AUTO, L"SET OutputRoot.XML.Result[] = (SELECT T.C1 AS Col1 FROM Database.TABLE AS T;"); ... cniSqlSelect(&rc, sqlExpr, destinationList, exceptionList, message, outMsg); cniSqlDeleteStatement(&rc, sqlExpr); ... }
有关 ESQL 的更多信息,请参阅ESQL 概述。
如果用户定义的节点主要使用 ESQL,则请考虑使用 compute 节点,请参阅Compute 节点。
cniFinalize(&rc, outMsg, CCI_FINALIZE_NONE);
if (terminalObject) { if (cniIsTerminalAttached(&rc, terminalObject)) { if (rc == CCI_SUCCESS) { cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg); } }
在上面的示例中,cniIsTerminalAttached 函数用于测试消息是否可以传播到指定的终端。如果您不使用 cniIsTerminalAttached 函数,且终端没有被连接器连接到另一个节点,则此消息没有传播且不返回任何警告消息。使用 cniIsTerminalAttached 函数来阻止这种情况的发生。
cniDeleteMessage(&rc, outMsg);
{ ... cniWriteBuffer(&rc, message); writeToDevice(cniBufferPointer(&rc, message), cniBufferSize(&rc, message)); ... }在该示例中,方法 writeToDevice 是一个将位流写到输出设备的、用户编写的方法。
注意,消息只能序列化一次。