-
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;
}
|