扩展 C 消息处理或输出节点的功能

开始之前

确保您已阅读并理解以下主题:
创建用户定义的节点后,可以使用以下选项:
  1. 访问消息数据
  2. 转换消息对象
  3. 访问 ESQL
  4. 传播消息
  5. 写到输出设备

访问消息数据

在许多情况下,用户定义的节点需要访问在它的输入终端上接收到的消息的内容。消息由语法元素的树表示。提供了实用程序函数组以用于消息管理、消息缓冲区访问、语法元素导航和语法元素访问。(请参阅 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 函数将它写到新的输出消息。您从输入消息复制元素,或者您可以创建新的元素并将它们连接到消息。新的元素通常在解析器的域中。

例如:
  1. 要将进入消息写到新的消息:
    {
    ...
      context = cniGetMessageContext(&rc, message)); 
      outMsg = cniCreateMessage(&rc, context)); 
    ...
    }
  2. 要制作新消息的副本:
    cniCopyElementTree(&rc, sourceElement, targetElement);
  3. 要修改目标元素的值:
    cniSetElementIntegerValue(&rc, targetElement, L"newValue", 8); 
  4. 在最终化和传播消息后,您必须使用 cniDeleteMessage 函数删除输出消息:
     cniDeleteMessage(&rc, outMsg);
作为转换的一部分,可能需要创建一个新的消息体。要创建一个新的消息体,可以使用以下函数:
cniCreateElementAsFirstChildUsingParsercniCreateElementAsLastChildUsingParser
cniCreateElementAfterUsingParser
cniCreateElementBeforeUsingParser
应该使用这些函数,因为它们是专门用于将解析器分配给消息树文件夹的。
创建消息体时,不要使用以下函数,因为它们不将拥有的解析器与文件夹关联起来。
cniCreateElementAsFirstChildcniCreateElementAsLastChildcniCreateElementAfter
cniCreateElementBefore

访问 ESQL

节点可以使用 Compute 节点 ESQL 语法调用 ESQL 表达式。您可以使用 ESQL 表达式创建和修改消息的组件,并且您可以使用 cniSqlCreateStatementcniSqlSelectcniSqlDeleteStatementcniSqlExecute 函数,引用来自外部数据库的输入消息和数据的元素。

例如,要从数据库表中的列的内容植入 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 节点更新结束

传播消息

在您传播消息之前,您必须确定您要传播的消息流数据,以及用于接收数据的终端。
  1. 如果消息已更改,您应该在使用 cniFinalize 函数传播消息之前,您应该先最终化消息。例如:
    cniFinalize(&rc, outMsg, CCI_FINALIZE_NONE);
  2. terminalObject 从用户定义的节点自己维护的列表派生而来。要将消息传播到输出终端,使用 cniPropagate 函数:
    if (terminalObject) {
        if (cniIsTerminalAttached(&rc, terminalObject)) {
          if (rc == CCI_SUCCESS) {
            cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg);
    }
    }

    更新开始在上面的示例中,cniIsTerminalAttached 函数用于测试消息是否可以传播到指定的终端。如果您不使用 cniIsTerminalAttached 函数,且终端没有被连接器连接到另一个节点,则此消息没有传播且不返回任何警告消息。使用 cniIsTerminalAttached 函数来阻止这种情况的发生。更新结束

  3. 如果传播消息后使用 cniCreateMessage 创建了一个新的输出消息,则您必须使用 cniDeleteMessage 函数删除输出消息:
     cniDeleteMessage(&rc, outMsg);

写到输出设备

转换后的消息需要序列化为位流。然后,可以访问位流并将它写到输出设备。您使用 cniWriteBuffer 函数将消息写到位流。例如:
{
...
  cniWriteBuffer(&rc, message);
  writeToDevice(cniBufferPointer(&rc, message), cniBufferSize(&rc, message));
...
}
在该示例中,方法 writeToDevice 是一个将位流写到输出设备的、用户编写的方法。

注意,消息只能序列化一次。

注: 当写到 WebSphere MQ 队列时,您必须使用提供的 MQOutput 节点,因为代理在内部保留了 WebSphere MQ 连结并在每线程的基础上处理打开队列,且高速缓存它们以优化性能。另外,当发生某个 WebSphere MQ 事件时,代理会处理恢复方案,如果在用户定义的输出节点中使用了 WebSphere MQ MQI 调用,则会有不利的影响。
声明 | 商标 | 下载 | | 支持 | 反馈
Copyright IBM Corporation 1999, 2006 最后更新:2006/05/19
as24989_