扩展 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/08/14
as24989_