cniSqlCreateModifyablePathExpression

Creates a modifiable SqlPathExpression object that represents the path specified by the path argument. Modifiable means that when navigated, path elements will be created if they do not already exist. This function returns a pointer to the PathExpression object which is used as input to the functions that navigate the path, namely the cniSqlNavigatePath family. There is an overhead involved in creating the expression so if the same path expression is to be used for every message then this function should be called once and the CciSqlPathExpression* that is returned should used in a call to cniSqlNavigate for each message. It is possible to use the CciSqlPathExpression on a different thread than it was created.

Syntax

CciSqlPathExpression* cniSqlCreateModifiablePathExpression( 
	int* returnCode,
	CciNode* nodeObject,
	CciChar* dataSourceName,
	CciChar* path);

Parameters

returnCode (output)
A NULL pointer input signifies that the user-defined node does not want to deal with errors. Any exceptions thrown during the execution of this call are re-thrown to the next upstream node in the flow. If input is not NULL, output will signify the success status of the call. If an exception occurs during execution, *returnCode will be set to CCI_EXCEPTION on output. A call to cciGetLastExceptionData will provide details of the exception. If an invalid nodeObject parameter was passed in, then returnCode will be set to CCI_INV_NODE_OBJECT. If an invalid path parameter, such as NULL or an empty string, was passed in then returnCode will be set to CCI_INV_ESQL_PATH_EXPR.
nodeObject (input)
Specifies the message flow processing node the ESQL Path Expression will be owned by. This pointer is passed to the cniCreateNodeContext implementation function. This parameter must not be NULL.
dataSourceName (input)
The ODBC data source name to be used if the statement references an external database. This parameter can be NULL.
path (input)
Pointer to a NULL terminated string of CciChars. This specifies the ESQL path expression to be created as defined by the ESQL field reference syntax diagram, except that it cannot include local ESQL variables, ESQL Reference variables, user defined functions, ESQL Namespace constants, because they cannot be declared. This parameter must not be NULL.

Return values

If successful, the address of the SQLPathExpression object is returned. If an error occurs, CCI_NULL_ADDR is returned and the return code parameter indicates the reason for the error. Once the SQLPathExpression is no longer needed, (typically when the node is deleted) it should be deleted by calling cniSqlDeletePathExpression.

Example

By adding the following code to the Transform node sample we could easily create an element, and all necessary ancestor elements with one function call.

We create the CciSQLPathExpression in the _Transform_createNodeContext function:

 {
        CciChar ucsPathExpressionString[32];
        char*   mbPathExpressionString =
                           "OutputRoot.XML.Request.A.B.C.D.E";
        /* convert our path string to unicode*/
        cciMbsToUcs(NULL,
            mbPathExpressionString,
            ucsPathExpressionString,
            32,
            BIP_DEF_COMP_CCSID);
        
        p->pathExpression =
                     cniSqlCreateModifiablePathExpression(
                                 NULL,
                                 nodeObject,
                                 NULL,/*we do not reference Database*/
                                 ucsPathExpressionString);
    }

and we can then use this CciSqlPathExpression later in the _Transform_evaluate function

{
      CciElement* newElement = 
               cniSqlNavigatePath(
                     NULL,
                    ((NODE_CONTEXT_ST *)context)->pathExpression,
                     message,
                     destinationList,
                     exceptionList,
                     outMsg,
                     NULL,/*we do not reference OutputLocalEnvironment*/
                     NULL/*we do not reference OutputLExceptionList*/);
}

So passing in the input message PluginSample.change.xml:

<Request
type="change">
  <CustomerAccount>01234567</CustomerAccount>
  <CustomerPhone>555-0000</CustomerPhone>
</Request>

we would see the following output message.

<Request
type="modify">
  <CustomerAccount>01234567</CustomerAccount>
  <CustomerPhone>555-0000</CustomerPhone>
  <A>
    <B>
      <C>
        <D/>
      </C>
    </B>
  </A>
</Request>
Using this approach as opposed to using cniCreateElementAsLastChild etc has the following advantages:
  • The path is more dynamic – the path string could be determined at deploy time e.g. based on a node attribute (we could create the CciSQLPathExpression in our cniSetAttribute implementation function).
  • While navigating to and creating the element, we make one function call instead of several. This is more apparent when the target element is deep within the tree structure.