Hitesh,
I put together a small example of how to use a message handler with 
Sablotron. Compile with sablot.h in the include path, link with 
sablot.lib. Hope this helps, just ask if anything's unclear.
Tom

Shah Hitesh Bhavanji wrote:

> Hi,
> I went through the sablot.h and code of sabcmd to find how it uses it, but
> could not makemuch sense out of it. Can I get one sample example to see,
> how to use handlers or some more documentation about handlers?
> -Hitesh.
> 
>> SablotGetMsgText doesn't return the last reported error, just the
>> template message for given code. To catch all error, you have to
>> implement message handler. See sablot.h, search SablotRegHandler.
>> HTH
>> Pavel
>> 
>>> Hi,
>>> I have written a simple wrapper over Sablotron 0.50 which does
>> 
> processing
> 
>>> and returns transformed output.
>>> The stripped code for the same is
>>> 
>>> 01 char* XSLTProcess(char* xmlStream, char* xslStream)
>>> 02 {
>>> 03   char *argums[] =
>>> 04    {
>>> 05       "/_stylesheet", xslStream,
>>> 06      "/_xmlinput", xmlStream,
>>> 07        "/_output", NULL,
>>> 08        NULL
>>> 09    };
>>> 10   int returncode =
>>> SablotProcess("arg:/_stylesheet","arg:/_xmlinput","arg:/_output",
>> 
> params,
> 
>>> argums, &resultStr);
>>> 11   if(returncode != 0)
>>> 12    {
>>> 13       myException exp(SablotGetMsgText(returncode));
>>> 14        throw exp;
>>> 15    }
>>> 16    else
>>> 17    {
>>> 18        cout << resultStr << endl;
>>> 19        if(resultStr == NULL)
>>> 20            cout << "Result is NULL" << endl;
>>> 21        else
>>> 22       {
>>> 23            transformedStream = new char[strlen(resultStr) + 1];
>>> 24           strcpy(transformedStream, resultStr);
>>> 25        }
>>> 26    }
>>> 27    SablotFree(resultStr);
>>> 28    return transformedStream;
>>> 29}
>>> 
>>> On line number 13, I am using char* SablotGetMsgText(int) for getting
>> 
> the
> 
>>> error message.
>>> Whenever xml stream is malformed, I get a error "XML parser error %s:
>> 
> %s".
> 
>>> How can I get get a message string that has all the '%s' resolved?
>>> Do I need to implement messagehandler? Where can I get documentation for
>> 
> the
> 
>>> same?
>>> 
>>> Thanks and Regards,
>>> Hitesh.
>>> 
>>> 
>>>> Could you be more specific?
>>>> Did you implement the message handler?
>>>> Which kind of message contains the %s format?
>>>> Pavel
>>>> 
>>>>> I am using sablotron for XSLT processing of a few simple xml.
>>>>> I have written my own processing class and in case of error messages,
>>>> 
> I
> 
>>>>> get a message
>>>>> containing %s.
>>>>> I wanted to know how to get a message that does not contain %s and
>>>>> instead has complete
>>>>> error string with all the parameters filled in.
>>>>> Thanks and Regards,
>>>>> Hitesh.
>>>>> Note:- I am using Sablotron in a C++ application.
>>>> 
>> 
>> --
>> Pavel Hlavnicka
>> Ginger Alliance Ltd.
>> Prague; Czech Republic
>> 

/*
  msghandler.c
  an example of a custom message handler for Sablotron
  Ginger Alliance, 2001
  use of this example program is not restricted

  see shandler.h and sablot.h for more information.

  Our message handler just prints all the available information about
  the messages it receives. We test it by running a newly created processor
  on invalid URLs.
*/

#include "stdio.h"
#include "stdlib.h"
#include "sablot.h"  /* this also includes shandler.h */


/***  AUXILIARY FUNCTIONS  ***/

char *levelNames[] = {"debug", "info", "warning", "error", "critical"};

/* dumps all the items of a NULL-terminated string array */
void dumpFields(char **fields)
{
    for (; *fields; fields++)
        printf("[%s] ",*fields);
    puts("\n");
}

void die(char *msg)
{
    puts(msg);
    exit(EXIT_FAILURE);
}


/***  MESSAGE HANDLER'S FUNCTIONS  ***/

/*
    my_makeCode should just put a few numbers together to produce
    an "application-global" error code. We just use the "facility" (i.e.
    the module number, which is always 2 for Sablotron) and the "code" (which
    relates to the module).
    The resulting global error code is what actually gets reported.
    As in the following functions, we don't care about userData; they will
    always be NULL as set upon registration.
*/

MH_ERROR my_makeCode(
    void *userData, SablotHandle processor_,
    int severity, unsigned short facility, unsigned short code)
{
    return (unsigned long)((facility << 10) | (code & 0x3ff));
}


/*
    my_log receives all log messages: code, severity level, and a series
    of string of the form "name:contents", where name can be e.g. "msgtype",
    "module", "code" (related to module), "msg" (the message itself).
*/

MH_ERROR my_log(
    void *userData, SablotHandle processor_,
    MH_ERROR code, MH_LEVEL level, char **fields)
{
    printf("LOG: code %d, level %s\n",code,levelNames[level]);
    dumpFields(fields);
    return 0;
}


/*
    my_error receives all error messages and warnings (which only differ in
    the severity level). See the decription of my_log.
*/

MH_ERROR my_error(
    void *userData, SablotHandle processor_,
    MH_ERROR code, MH_LEVEL level, char **fields)
{
    printf("ERROR: code %d, level %s\n",code,levelNames[level]);
    dumpFields(fields);
    return 0;
}


/***  THE HANDLER STRUCT  ***/

MessageHandler my_handler=
{ my_makeCode, my_log, my_error };


/***  MAIN  ***/

void main(void)
{
    /* create a processor... */
    SablotHandle P;
    if (SablotCreateProcessor(&P))
        die("couldn't create processor");

    /* register a message handler */
    /* the userData received by the callbacks will be NULL (the last arg) */
    if (SablotRegHandler(P, HLR_MESSAGE, &my_handler, NULL))
        die("couldn't register handler");

    /* run the processor on nonexistent files to get an error */
    SablotRunProcessor(P, "some", "nonsense", "here", NULL, NULL);

    /* destroy the processor */
    SablotDestroyProcessor(P);
}

Reply via email to