/*
* Copyright (C) 2004 SIPfoundry Inc.
* Licensed by SIPfoundry under the LGPL license.
*
* Copyright (C) 2004 Pingtel Corp.
* Licensed to SIPfoundry under a Contributor Agreement.
*
* Derived from: xerces-c sample application DOMCount, which is
* Copyright 1999-2002,2004 The Apache Software Foundation.
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/AbstractDOMParser.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMBuilder.hpp>
#include <xercesc/dom/DOMException.hpp>
#include <xercesc/dom/DOMDocument.hpp>
#include <xercesc/dom/DOMError.hpp>
#include <xercesc/dom/DOMLocator.hpp>
#include <xercesc/dom/DOMErrorHandler.hpp>
#include <xercesc/util/XMLString.hpp>
#include "utl/UtlString.h"
#include "sipxcommserverlib-buildstamp.h"
#if defined(XERCES_NEW_IOSTREAMS)
#include <iostream>
#else
#include <iostream.h>
#endif
#include <string.h>
#include <stdlib.h>
XERCES_CPP_NAMESPACE_USE
// ---------------------------------------------------------------------------
// Simple error handler deriviative to install on parser
// ---------------------------------------------------------------------------
class XSDValidErrorHandler : public DOMErrorHandler
{
public:
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
XSDValidErrorHandler();
~XSDValidErrorHandler();
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
bool getSawErrors() const;
// -----------------------------------------------------------------------
// Implementation of the DOM ErrorHandler interface
// -----------------------------------------------------------------------
bool handleError(const DOMError& domError);
void resetErrors();
private :
// -----------------------------------------------------------------------
// Unimplemented constructors and operators
// -----------------------------------------------------------------------
XSDValidErrorHandler(const XSDValidErrorHandler&);
void operator=(const XSDValidErrorHandler&);
// -----------------------------------------------------------------------
// Private data members
//
// fSawErrors
// This is set if we get any errors, and is queryable via a getter
// method. Its used by the main code to suppress output if there are
// errors.
// -----------------------------------------------------------------------
bool fSawErrors;
};
// ---------------------------------------------------------------------------
// This is a simple class that lets us do easy (though not terribly efficient)
// trancoding of XMLCh data to local code page for display.
// ---------------------------------------------------------------------------
class StrX
{
public :
// -----------------------------------------------------------------------
// Constructors and Destructor
// -----------------------------------------------------------------------
StrX(const XMLCh* const toTranscode)
{
// Call the private transcoding method
fLocalForm = XMLString::transcode(toTranscode);
}
~StrX()
{
XMLString::release(&fLocalForm);
}
// -----------------------------------------------------------------------
// Getter methods
// -----------------------------------------------------------------------
const char* localForm() const
{
return fLocalForm;
}
private :
// -----------------------------------------------------------------------
// Private data members
//
// fLocalForm
// This is the local code page form of the string.
// -----------------------------------------------------------------------
char* fLocalForm;
};
inline XERCES_STD_QUALIFIER ostream& operator<<(XERCES_STD_QUALIFIER ostream& target, const StrX& toDump)
{
target << toDump.localForm();
return target;
}
inline bool XSDValidErrorHandler::getSawErrors() const
{
return fSawErrors;
}
#if defined(XERCES_NEW_IOSTREAMS)
#include <fstream>
#else
#include <fstream.h>
#endif
// ---------------------------------------------------------------------------
// This is a simple program which invokes the DOMParser to build a DOM
// tree for the specified input file. It then walks the tree and counts
// the number of elements. The element count is then printed.
// ---------------------------------------------------------------------------
static void usage()
{
XERCES_STD_QUALIFIER cout <<
"\nUsage:\n"
" xsdvalid [<options>] <XML file> "
# ifdef LISTMODE
"| -l <List file>"
# endif
"\n"
"\n"
"Validates an XML instance document against its schema as determined\n"
"by examining the attributes in the document.\n"
"\n"
"Options:\n"
" --version prints the version number\n"
" -s|--schema <namespace> <schema-location>\n"
" Specifies a namespace and the location of a local copy of the \n"
" schema definition file for that namespace.\n"
" (may be repeated for multiple namespaces)\n"
# ifdef LISTMODE
" -l Indicate the input file is a List File that has a list of xml files.\n"
" Default to off (Input file is an XML file).\n"
# endif
" -? Show this help.\n"
"\n"
" Returns zero if the file is valid, non-zero if not.\n"
"\n"
<< XERCES_STD_QUALIFIER endl;
}
// ---------------------------------------------------------------------------
//
// main
//
// ---------------------------------------------------------------------------
int main(int argC, char* argV[])
{
// Check command line and extract arguments.
if (argC < 2)
{
usage();
return 1;
}
const char* xmlFile = 0;
AbstractDOMParser::ValSchemes valScheme = AbstractDOMParser::Val_Always;
bool doNamespaces = true;
bool doSchema = true;
bool schemaFullChecking = true;
bool doList = false;
bool errorOccurred = false;
char localeStr[64];
UtlString schemaLocationPairs;
UtlString defaultSchema;
memset(localeStr, 0, sizeof localeStr);
int argInd;
for (argInd = 1; argInd < argC; argInd++)
{
// Break out on first parm not starting with a dash
if (argV[argInd][0] != '-')
break;
// Watch for special case help request
if (!strcmp(argV[argInd], "-?"))
{
usage();
return 2;
}
if (!strcmp(argV[argInd], "--version"))
{
XERCES_STD_QUALIFIER cerr
<< "xsdvalid version " << SipXcommserverlibVersion
<< " build " << SipXcommserverlibBuildStamp
<< "\n" << XERCES_STD_QUALIFIER endl;
return 0;
}
else if (!strcmp(argV[argInd], "-l")
|| !strcmp(argV[argInd], "-L"))
{
doList = true;
}
else if ( !strncmp(argV[argInd], "-s", 2)
|| !strncmp(argV[argInd], "--schema", 9)
)
{
if (argInd+2 < argC)
{
if (!schemaLocationPairs.isNull())
{
schemaLocationPairs.append(" ");
}
schemaLocationPairs.append(argV[++argInd]);
schemaLocationPairs.append(" ");
schemaLocationPairs.append(argV[++argInd]);
}
else
{
XERCES_STD_QUALIFIER cerr
<< "Option '" << argV[argInd]
<< "' must be followed by <schema-namespace> <schema-location>\n"
<< XERCES_STD_QUALIFIER endl;
return 2;
}
}
else
{
XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[argInd]
<< "', ignoring it\n" << XERCES_STD_QUALIFIER endl;
}
}
//
// There should be only one and only one parameter left, and that
// should be the file name.
//
if (argInd != argC - 1)
{
usage();
return 1;
}
// Initialize the XML4C system
try
{
if (strlen(localeStr))
{
XMLPlatformUtils::Initialize(localeStr);
}
else
{
XMLPlatformUtils::Initialize();
}
}
catch (const XMLException& toCatch)
{
XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"
<< StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
return 1;
}
catch (...)
{
XERCES_STD_QUALIFIER cerr << "Unexpected error during initialization!\n";
return 1;
}
// Instantiate the DOM parser.
static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
DOMBuilder *parser = ((DOMImplementationLS*)impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
parser->setFeature(XMLUni::fgDOMNamespaces, doNamespaces);
parser->setFeature(XMLUni::fgXercesSchema, doSchema);
parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
if (valScheme == AbstractDOMParser::Val_Auto)
{
parser->setFeature(XMLUni::fgDOMValidateIfSchema, true);
}
else if (valScheme == AbstractDOMParser::Val_Never)
{
parser->setFeature(XMLUni::fgDOMValidation, false);
}
else if (valScheme == AbstractDOMParser::Val_Always)
{
parser->setFeature(XMLUni::fgDOMValidation, true);
}
if (!schemaLocationPairs.isNull())
{
XMLCh* propertyValue = XMLString::transcode(schemaLocationPairs.data());
parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,
propertyValue
);
}
// enable datatype normalization - default is off
parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
// And create our error handler and install it
XSDValidErrorHandler errorHandler;
parser->setErrorHandler(&errorHandler);
//
// Get the starting time and kick off the parse of the indicated
// file. Catch any exceptions that might propogate out of it.
//
unsigned long duration;
bool more = true;
XERCES_STD_QUALIFIER ifstream fin;
// the input is a list file
if (doList)
fin.open(argV[argInd]);
if (fin.fail()) {
XERCES_STD_QUALIFIER cerr <<"Cannot open the list file: " << argV[argInd] << XERCES_STD_QUALIFIER endl;
return 2;
}
while (more)
{
char fURI[1000];
//initialize the array to zeros
memset(fURI,0,sizeof(fURI));
if (doList) {
if (! fin.eof() ) {
fin.getline (fURI, sizeof(fURI));
if (!*fURI)
continue;
else {
xmlFile = fURI;
XERCES_STD_QUALIFIER cerr << "==Parsing== " << xmlFile << XERCES_STD_QUALIFIER endl;
}
}
else
break;
}
else {
xmlFile = argV[argInd];
more = false;
}
//reset error count first
errorHandler.resetErrors();
XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc = 0;
try
{
// reset document pool
parser->resetDocumentPool();
const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
doc = parser->parseURI(xmlFile);
const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
duration = endMillis - startMillis;
}
catch (const XMLException& toCatch)
{
XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << xmlFile << "'\n"
<< "Exception message is: \n"
<< StrX(toCatch.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl;
errorOccurred = true;
continue;
}
catch (const DOMException& toCatch)
{
const unsigned int maxChars = 2047;
XMLCh errText[maxChars + 1];
XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << xmlFile << "'\n"
<< "DOMException code is: " << toCatch.code << XERCES_STD_QUALIFIER endl;
if (DOMImplementation::loadDOMExceptionMsg(toCatch.code, errText, maxChars))
XERCES_STD_QUALIFIER cerr << "Message is: " << StrX(errText) << XERCES_STD_QUALIFIER endl;
errorOccurred = true;
continue;
}
catch (...)
{
XERCES_STD_QUALIFIER cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
errorOccurred = true;
continue;
}
}
//
// Delete the parser itself. Must be done prior to calling Terminate, below.
//
parser->release();
// And call the termination method
XMLPlatformUtils::Terminate();
if (doList)
fin.close();
return errorOccurred || errorHandler.getSawErrors() ? 1 : 0;
}
XSDValidErrorHandler::XSDValidErrorHandler() :
fSawErrors(false)
{
}
XSDValidErrorHandler::~XSDValidErrorHandler()
{
}
// ---------------------------------------------------------------------------
// XSDValidHandlers: Overrides of the DOM ErrorHandler interface
// ---------------------------------------------------------------------------
bool XSDValidErrorHandler::handleError(const DOMError& domError)
{
fSawErrors = true;
if (domError.getSeverity() == DOMError::DOM_SEVERITY_WARNING)
{
XERCES_STD_QUALIFIER cerr << "\nWarning at file ";
}
else if (domError.getSeverity() == DOMError::DOM_SEVERITY_ERROR)
{
XERCES_STD_QUALIFIER cerr << "\nError at file ";
}
else
{
XERCES_STD_QUALIFIER cerr << "\nFatal Error at file ";
}
XERCES_STD_QUALIFIER cerr << StrX(domError.getLocation()->getURI())
<< ", line " << domError.getLocation()->getLineNumber()
<< ", char " << domError.getLocation()->getColumnNumber()
<< "\n Message: " << StrX(domError.getMessage()) << XERCES_STD_QUALIFIER endl;
return true;
}
void XSDValidErrorHandler::resetErrors()
{
fSawErrors = false;
}
syntax highlighted by Code2HTML, v. 0.9.1