//These are global in the program //Handler pointers D warningHandler@... D S * procptr D inz(%paddr('HANDLEWARNING')) D errorHandler@... D S * procptr D inz(%paddr('HANDLEERROR')) D resetHandler@... D S * procptr D inz(%paddr('HANDLERESET')) D fatalHandler@... D S * procptr D inz(%paddr('HANDLEFATAL')) P*-------------------------------------------------- P* Procedure name: ValidateBuffer P* Purpose: Given a buffer and its length parses it in and reco... P* rds any errors in Validation Error... P* P* Returns: The return code of the operation P* Parameter: buffer => the memory buffer to parse and validate P* Parameter: bufferLength => the number of bytes in the buffer P* Parameter: DoNamespaces => Whether or not to enforce namespaces P* Parameter: DoSchema => Allows enabling of processing any schem... P* as encountered in the document P* Parameter: DoSchemaFullChecking => Enables full checking (some... P* full checking items are RAM and CPU inten... P* sive) P* Parameter: EncodingString => A string that states the buffers ... P* encoding, if not supplied defaults to UTF-8 P* Parameter: EncodingStringLength => THe number of bytes in the ... P* encoding string, defaults to 5 P* Parameter: EncodingStringCCSID => the ccsid of the encoding st... P* ring field, defaults to 285 P*-------------------------------------------------- P ValidateBuffer... P B Export D ValidateBuffer... D PI 10A D buffer * VALUE D bufferLength 10U 0 D EncodingString * VALUE D OPTIONS(*NOPASS) D EncodingStringLength... D 10U 0 VALUE D OPTIONS(*NOPASS) D EncodingStringCCSID... D 10U 0 VALUE D OPTIONS(*NOPASS) D* Local fields D retField S 10A Inz('') D saxParse@ s * D errorHandler@ s * D memBuffer@ s * DbufId S 1a Dbufid@ S * INZ(%addr(bufid)) D wrkEncStg s * D wrkEncStgLen s 10u 0 D wrkEncCCSID s 10u 0 D parmsSupplied... D s 10u 0 D false s 10i 0 inz(0) D defaultEnc s 5a inz('UTF-8') D wrkErrorInstance... D S 10p 0 saxParse@ = QxmlXMLReaderFactory_createXMLReader(); //Set parser options SetParserOptions(saxParse@:Session.DoNamespaces :Session.DoSchema:Session.DoFullSchema); errorHandler@ = QxmlErrorHandler_new(); QxmlSAX2XMLReader_setErrorHandler (SAXParse@: errorHandler@); RegisterErrorEvents(errorHandler@); membuffer@ = CreateMumBufInputSource(buffer:bufferLength: wrkEncStg:wrkEncCCSID:wrkEncStgLen); QxmlSAX2XMLReader_parse_InputSource(SAXParse@:membuffer@); //If this failed then send an error if Qxml_DOMEXCDATA.Qxml_DOMRTNCOD <> 0; //log rtn code in job log retField = 'ERROR'; endif; ClearSAXResources(saxParse@:memBuffer@:errorHandler@); //Decide on return code based on types of error SELECT; WHEN Session.SaxHasFatal; retField = 'FATAL'; WHEN Session.SaxHasError; retField = 'ERROR'; WHEN Session.SaxHasReset; retField = 'RESET'; WHEN Session.SaxHasWarning; retField = 'WARNING'; ENDSL; /END-FREE P ValidateBuffer... P E P*-------------------------------------------------- P* Procedure name: SetParserOptions P* Purpose: Sets the main options on a SAX Parser P* This method also looks up the Namespace group header P* and if it exists sets the schema locations as appropriate P* Returns: P* Parameter: saxParser => The saxparser to set the options on P* Parameter: DoNamespaces P* Parameter: doSchema P* Parameter: DoFullSchema P*-------------------------------------------------- P SetParserOptions... P B D SetParserOptions... D PI D saxParser * VALUE D DoNamespaces N VALUE D doSchema N VALUE D DoFullSchema N VALUE D true C 1 D ESY2rtnCode s 7a D SchemaList s 2048a D prop s 100a inz('http://apache.org/xml/propertie+ D s/schema/external-schemaLocation') D SchemaListC s 2049C D Dvalfeature S 90A INZ('http://xml.org/sax/features/va+ D lidation') Dvalfeatdyn S 90A INZ('http://apache.org/xml/features/+ D validation/dynamic') Dnamespfeat S 90A INZ('http://xml.org/sax/features/+ D namespaces') Dschemafeat S 90A INZ('http://apache.org/xml/features/+ D validation/schema') Dschfullchk S 90A INZ('http://apache.org/xml/features/+ D validation/schema-full-+ D checking') /FREE //Turn on validation QxmlSAX2XMLReader_enableFeature(saxParser:%addr(valfeature) :285:%len(%trimr(valfeature))); QxmlSAX2XMLReader_enableFeature(saxParser:%addr(valfeatdyn):285 :%len(%trimr(valfeatdyn))); //Set namespaces if DoNamespaces; QxmlSAX2XMLReader_enableFeature(saxParser:%addr(namespfeat):285 :%len(%trimr(namespfeat))); //Set do schema if doSchema; Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlSAX2XMLReader_enableFeature(saxParser:%addr(schemafeat):285 :%len(%trimr(schemafeat))); //Set do full schema if DoFullSchema; Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlSAX2XMLReader_enableFeature(saxParser:%addr(schfullchk):285 :%len(%trimr(schfullchk))); SchemaList = 'Set your schema list here'; // like 'NameSpaceURI file://root/blah/myschema.xsd AnotherNamespaceURI file://root/blahdeblah/mySchema2.xsd' if SchemaList <> ''; //No point setting a blank schema list SchemaListC = %trimr(%ucs2(SchemaList)) + U'0000'; QxmlSAX2XMLReader_setProperty(saxParser:%addr(prop):285 :%len(%trimr(prop)): %addr(SchemaListC)); endif; endif; return; /END-FREE P SetParserOptions... P E P*-------------------------------------------------- P* Procedure name: RegisterErrorEvents P* Purpose: Registers the relevant error events on the error ha... P* ndler P* Returns: P* Parameter: ErrorHandler => The error handler to register the e... P* vents on P*-------------------------------------------------- P RegisterErrorEvents... P B D RegisterErrorEvents... D PI D ErrorHandler * VALUE /FREE //register warnings QxmlErrorHandler_setCallback (ErrorHandler: Qxml_WARNINGHNDLR: warningHandler@); //register error Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlErrorHandler_setCallback (ErrorHandler: Qxml_ERRORHNDLR: errorHandler@); //register fatal Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlErrorHandler_setCallback (ErrorHandler: Qxml_FATALERRORHNDLR: fatalHandler@); //register reset // QxmlErrorHandler_setCallback // (ErrorHandler: // Qxml_RESETERRORHNDLR: // resetHandler@); /END-FREE P RegisterErrorEvents... P E P*-------------------------------------------------- P* Procedure name: ClearSAXResources P* Purpose: Clears up after usage of the SAX parser, deletes th... P* e parser, membuf input, error handler and ... P* closes down the two synon functions if the... P* y were called P* Returns: P* Parameter: Parser => The parser that was used P* Parameter: MemorySource => The memeory source that was used P* Parameter: ErrorHandler => the error handler that was used P*-------------------------------------------------- P ClearSAXResources... P B D ClearSAXResources... D PI D Parser * VALUE D MemorySource * VALUE D ErrorHandler * VALUE D Function s 1a inz('N') D Closedown s 1a inz('Y') /FREE //Delete the memory source Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlMemBufInputSource_delete(MemorySource); //Delete the error handler Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlErrorHandler_delete(ErrorHandler); //Delete the parser Qxml_DOMEXCDATA.Qxml_DOMRTNCOD = 0; QxmlSAX2XMLReader_delete(Parser); /END-FREE P ClearSAXResources... P E P*-------------------------------------------------- P* Procedure name: HandleWarning P* Purpose: Handles any warnings that are thrown by the SAX parser P* Returns: Nothing P* Parameter: SaxParserException => THe exception that is thrown ... P* by the parser P*-------------------------------------------------- P HandleWarning... P B D HandleWarning... D PI D SaxParserException... D * VALUE /FREE //Only if not ignoring warnings if not Session.SaxIgnoreWarning ; //Track that warning has been Session.SaxHasWarning = *on; endif; /END-FREE P HandleWarning... P E P*-------------------------------------------------- P* Procedure name: HandleError P* Purpose: Handles parser errors P* Returns: P* Parameter: SaxParserException => THe exception that was thrown P*-------------------------------------------------- P HandleError... P B D HandleError... D PI D SaxParserException... D * VALUE /FREE //Only if not ignoring errors if not Session.SaxIgnoreErrors; //Track the fact we have had an error Session.SaxHasError = *on; if Session.DumpValidation; //Report a warning diagnostic with the current surrogate ReportDiagnostic('E':SaxParserException); endif; endif; /END-FREE P HandleError... P E P*-------------------------------------------------- P* Procedure name: HandleFatal P* Purpose: Handles fatal parser exceptions P* Returns: P* Parameter: SaxParserException => The sax exception P*-------------------------------------------------- P HandleFatal... P B D HandleFatal... D PI D SaxParserException... D * VALUE /FREE //Only if not ignoring fatals if not Session.SaxIgnoreFatal; //Track the fact that we have had a fatal Session.SaxHasFatal = *on; if Session.DumpValidation; //Report a warning diagnostic with the current surrogate ReportDiagnostic('F':SaxParserException); endif; endif; /END-FREE P HandleFatal... P E P*-------------------------------------------------- P* Procedure name: ReportDiagnostic P* Purpose: Reports a diagnostic given a type and a sax parser ... P* exception P* Returns: P* Parameter: Type P* Parameter: SaxParserException => the exception that was thrown P*-------------------------------------------------- P ReportDiagnostic... P B D ReportDiagnostic... D PI D Type 1A VALUE D SaxParserException... D * VALUE D Line S 10I 0 D Col S 10I 0 D Msg@ S * Dtransmsg S 250A DTRANSMSG@ S * INZ(%ADDR(transmsg)) DErrprov S 10I 0 INZ(200) DErravail S 10I 0 INZ(0) D LinePacked s 5P 0 D ColPacked s 5P 0 D wrkErrIns s 10P 0 D Function s 1a INZ('P') D Closedown s 1a INZ('N') D rtnCode s 7a /FREE //Get the line number LINE=QxmlSAXParseException_getLineNumber (SaxParserException); //Get the column number COL =QxmlSAXParseException_getColumn... Number(SaxParserException); //Get the exception message MSG@= QxmlSAXException_getMessage (SaxParserException); //Convert it to our CCSID QxmlTranscode(MSG@: Qxml_UNICODE: TRANSMSG@: %ADDR(ErrPROV): %ADDR(ErrAVAIL): 285); //Convert line and col to packed LinePacked = %dec(Line); ColPacked = %dec(Col); //whatever you feel you need to do here with the info above return; /END-FREE P ReportDiagnostic... P E