XML for RPG and Procedural Languages Documentation

Readme
Installation
API Docs
Samples
Programming
License

C: SAXCount

The Code: qcsrc.SAXCount

    The lines of code that correspond to XML parser initialization, use and clean-up are displayed in blue.

/********************************************************************
  SAXCount -- This sample program uses the SAX parser and
 *            counts the number of elements and attributes in an XML document.
 *            The xml file to be counted is input by the user.
 ********************************************************************
*/

/*INCLUDES*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <qxml4pr400.h>   /* DOM/SAX api headers */
#define true 1
#define false 0

/*PROTOTYPES*/
void usage (void);
void startElement(const XMLCh* const name, AttributeList  attributes);
void characters(const XMLCh* const chars , const unsigned int length);
void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
void resetDocument();
void error(const SAXParseException e);
void fatalError(const SAXParseException e);
void warning(const SAXParseException e);


char *xmlFile;		/*the XML file name in local IFS */
QxmlXML_env_t env;	/*the XML environment            */
QxmlParser_env_t P_env;	/*the XML parser environment     */
int fElementCount = 0;	/*count for # of elements        */
int fAttrCount = 0;	/*count for # of attributes      */
int fCharacterCount = 0;/*count for # of characters      */
int fSpaceCount = 0;	/*count for # of spaces          */
int errorind = 0;	/*find whether an error occured or not*/

/*usage - the way this program takes input, called if input is incorrect*/
void usage ()
{
    printf("\nUsage:\n");
    printf("    SAXCount [-v] <XML file>\n");
    printf("    -v  Do a validating parse. Defaults to non-validating.\n");
    printf("    -v= xxx  Validation scheme [always | never | auto*].\n");
    printf("    -n       Enable namespace processing. Defaults to off.\n");
    printf("    -s       Enable schema processing. Defaults to off.\n");
    printf("    -f       Enable full schema constraint checking. Defaults to off.\n");
    printf("This program prints the number of elements, attributes,\n");
    printf("white spaces and other non-white space characters in the \n");
    printf("input file.\n");
}

/* ---------------------------------------------------------------------------
   Implementation of the SAX DocumentHandler interface
 ---------------------------------------------------------------------------*/
void startElement(const XMLCh* const name, AttributeList  attributes)
{
    fElementCount++;	/*increment the amount of total elements, used to total*/
    fAttrCount = fAttrCount + QxmlAttributeList_getLength (attributes);/*also incrementing # of attributes*/
}
void characters(const XMLCh* const chars , const unsigned int length)
{
    fCharacterCount = fCharacterCount + length;  /*increment the # of characters*/
}
void ignorableWhitespace(const XMLCh* const chars, const unsigned int length)
{
    fSpaceCount = fSpaceCount + length;  /*increment the spacecount*/
}
void resetDocument()  /*used to reset the document, set everything back to 0*/
{
    fAttrCount = 0;
    fCharacterCount = 0;
    fElementCount = 0;
    fSpaceCount = 0;
}

/* ---------------------------------------------------------------------------
    Implementation of the SAX ErrorHandler interface
 ---------------------------------------------------------------------------*/
void error(const SAXParseException e)  /*error occured*/
{
    char outputstring[300];  /*output buffer used for transcode requests*/
    int bytesprovided = 300; /*space you are giving*/
    int bytesavailable = 0;  /*bytes used by parse*/
    /*output error information*/
    errorind = 1;
    printf("\nError at (file ");
    QxmlTranscode
      (QxmlSAXParseException_getSystemId(e),
      Qxml_UNICODE,
      outputstring,
      &bytesprovided,
      &bytesavailable,
      Qxml_CCSID37);
    outputstring[bytesavailable] = '\0'; /*null terminate the output*/
    printf(outputstring);   /*print the output*/
    printf(", line ");
    printf("%i", QxmlSAXParseException_getLineNumber(e));
    printf(", char ");
    printf("%i", QxmlSAXParseException_getColumnNumber(e));
    printf("):\n ");
    QxmlTranscode
      (QxmlSAXException_getMessage(e),
      Qxml_UNICODE,
      outputstring,
      &bytesprovided,
      &bytesavailable,
      Qxml_CCSID37);  /* transcode message from unicode to provided CCSID */
    outputstring[bytesavailable] = '\0'; /*null terminate the output*/
    printf(outputstring);   /*print the output*/
}


/*main - will parse XML document and count elements, attributes, characters and whitespace*/
int main (int argc, char *args[])
{
    /* Provide function prototypes for use on the SAX handler call backs*/
    void (*fcharacters)(const XMLCh* const chars,const unsigned int length);
    void (*fignorableWhitespace)(const XMLCh* const target,const unsigned int data);
    void (*fresetDocument)();
    void (*fstartElement)(const XMLCh*const names,AttributeList attributes);
    void (*fwarning)(SAXParseException exception);
    void (*ferrors)(SAXParseException exception);
    void (*ffatalError) ( SAXParseException exception);

    /*variables*/
    int valScheme = Qxml_AUTO_VALIDATE;	/*whether DTD validation will occur*/
    int doNamespaces       = false;    /* namespace processing */
    int doSchema           = false;    /* schema processing */
    int schemaFullChecking = false;    /* full schema constraint checking */
    int argInd ;

    SAXParser parser;			/*the SAX parser*/
    DocumentHandler dochandler;		/*handles SAX document handler events*/
    ErrorHandler errhandler;		/*handles SAX error handler events*/

    /*initialize the environment - this must be done before any other DOM/SAX API*/
    QxmlInit(&env);

    /*We only have one required parameter, which is the file to process*/
    if (argc < 2)
    {
        usage();
        QxmlTerm();
        return -1;
    }


    /*Check for some special cases values of the parameter*/
    if ((argc == 2) && !strcmp(argv[1], "-?"))
    {
        usage();
        QxmlTerm();
        return 0;
    }
    for (argInd = 1; argInd < argc; argInd++)
    {
        /* Break out on first non-dash parameter */
        if (argv[argInd][0] != '-')
            break;

        if (!strncmp(argv[argInd], "-v=", 3) ||  !strncmp(argv[argInd], "-V=", 3))
        {
            const char* const parm = &argv[argInd][3];

            if (!strcmp(parm, "never"))
                valScheme = QxmlNEVER_VALIDATE;
            else if (!strcmp(parm, "auto"))
                valScheme = QxmlAUTO_VALIDATE;
            else if (!strcmp(parm, "always"))
                valScheme = QxmlALWAYS_VALIDATE;
            else
            {
                printf("Unknown -v= value: \t %s\n", parm );
                return 2;
            }
        }
        else
            if ((!strcmp(argv[argInd], "-n")||!strcmp(argv[argInd], "-N")))
                doNamespaces = true;
        else
            if ((!strcmp(argv[argInd], "-s")||!strcmp(argv[argInd], "-S")))
                doSchema = true;
        else
            if ((!strcmp(argv[argInd], "-f")||!strcmp(argv[argInd], "-F")))
                schemaFullChecking = true;
        else
            printf("Unknown option,  %s , ignoring it\n ", argv[argInd]);

    }

    /*  There should be only one and only one parameter left,
        and that should be the file name. */
    if (argInd != argc - 1)
    {
        usage();
        QxmlTerm();
        return 1;
    }
    xmlFile = argv[argInd];


    /*Instantiate the SAX parser*/
    parser = QxmlSAXParser_new ();
    /* setDoValidation has been depreciated as a C++ parser function
       and is here for upward compatiblity.  Switch to use
       setValidationScheme */
    QxmlSAXParser_setValidationScheme (parser, valScheme);
    QxmlSAXParser_setDoNamespaces(parser, doNamespaces);
    QxmlSAXParser_setDoSchema(parser, doSchema);
    QxmlSAXParser_setValidationSchemaFullChecking(parser, schemaFullChecking);

    /*Create a SAX document and error handler and install it on the parser */
    dochandler = QxmlDocumentHandler_new();
    errhandler = QxmlErrorHandler_new();
    QxmlSAXParser_setDocumentHandler(parser, dochandler);
    QxmlSAXParser_setErrorHandler(parser, errhandler);

    /*Set the functions pointers to the address of the callback routines */
    fstartElement = startElement;
    fcharacters = characters;
    fignorableWhitespace = ignorableWhitespace;
    fresetDocument = resetDocument;

    fwarning = error;
    ferrors = error;
    ffatalError = error;

    /*set up the call backs*/
    /*these functions will be called during the parse */
    QxmlDocumentHandler_setCallback (dochandler, Qxml_STARTELEMENT, (void*)(&fstartElement));
    QxmlDocumentHandler_setCallback (dochandler, Qxml_CHARACTERS, (void*)(&fcharacters));
    QxmlDocumentHandler_setCallback (dochandler, Qxml_IGNORABLEWHSP, (void*)(&fignorableWhitespace));
    QxmlDocumentHandler_setCallback (dochandler, Qxml_RESETDOCUMENT, (void*)(&fresetDocument));
    QxmlErrorHandler_setCallback (errhandler, Qxml_WARNINGHNDLR, (void *)(&fwarning));
    QxmlErrorHandler_setCallback (errhandler, Qxml_ERRORHNDLR, (void *)(&ferrors));
    QxmlErrorHandler_setCallback (errhandler, Qxml_FATALERRORHNDLR, (void *)(&ffatalError));

    /* Parse the document*/
    QxmlSAXParser_parse_SystemId (parser, (void *)xmlFile, Qxml_CCSID37,0);
    if (env.rtncode != 0)  /*error occured in the env, SAXCount aborted*/
	      return -1;

    /*output, telling elements, etc.*/
    printf("\n");
    printf(xmlFile);
    printf("\n%i", fElementCount);
    printf(" Elements \n");
    printf("%i", fAttrCount);
    printf(" Attributes \n");
    printf("%i", fCharacterCount);
    printf(" Characters \n");
    printf("%i", fSpaceCount);
    printf(" Spaces \n\n");

    QxmlDocumentHandler_delete (dochandler);
    QxmlErrorHandler_delete (errhandler);
    QxmlSAXParser_delete (parser);
    QxmlTerm();
    return 0;
}

	

XML4PR - XML4C Interface Wrapper for RPG, C and COBOL
Copyright 2000,2001,2002 International Business Machines. All Rights Reserved.