/DetectorDescription/RegressionTest/test/simple_dom_parser.cpp

https://github.com/aivanov-cern/cmssw · C++ · 316 lines · 229 code · 38 blank · 49 comment · 52 complexity · 89faf934b87b88851150384b5c9c09ef MD5 · raw file

  1. #include "DetectorDescription/RegressionTest/src/SaxToDom.h"
  2. #include "DetectorDescription/RegressionTest/src/TinyDomTest.h"
  3. #include "DetectorDescription/RegressionTest/src/StrX.h"
  4. #include "FWCore/Concurrency/interface/Xerces.h"
  5. #include <xercesc/sax2/SAX2XMLReader.hpp>
  6. #include <xercesc/sax2/XMLReaderFactory.hpp>
  7. #include <fstream>
  8. #include <map>
  9. #include <stdlib.h>
  10. using namespace std;
  11. class ADummy
  12. {
  13. };
  14. // ---------------------------------------------------------------------------
  15. // Local helper methods
  16. // ---------------------------------------------------------------------------
  17. void usage()
  18. {
  19. cout << "\nUsage:\n"
  20. " SAX2Count [options] <XML file | List file>\n\n"
  21. "This program invokes the SAX2XMLReader, and then prints the\n"
  22. "number of elements, attributes, spaces and characters found\n"
  23. "in each XML file, using SAX2 API.\n\n"
  24. "Options:\n"
  25. " -l Indicate the input file is a List File that has a list of xml files.\n"
  26. " Default to off (Input file is an XML file).\n"
  27. " -v=xxx Validation scheme [always | never | auto*].\n"
  28. " -f Enable full schema constraint checking processing. Defaults to off.\n"
  29. " -p Enable namespace-prefixes feature. Defaults to off.\n"
  30. " -n Disable namespace processing. Defaults to on.\n"
  31. " NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.\n"
  32. " -s Disable schema processing. Defaults to on.\n"
  33. " NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.\n"
  34. " -? Show this help.\n\n"
  35. " * = Default if not provided explicitly.\n"
  36. << endl;
  37. }
  38. // ---------------------------------------------------------------------------
  39. // Program entry point
  40. // ---------------------------------------------------------------------------
  41. int main(int argC, char* argV[])
  42. {
  43. // Initialize the XML4C2 system
  44. try
  45. {
  46. cms::concurrency::xercesInitialize();
  47. }
  48. catch (const XMLException& toCatch)
  49. {
  50. cerr << "Error during initialization! Message:\n"
  51. << StrX(toCatch.getMessage()) << endl;
  52. return 1;
  53. }
  54. // Check command line and extract arguments.
  55. if (argC < 2)
  56. {
  57. usage();
  58. cms::concurrency::xercesTerminate();
  59. return 1;
  60. }
  61. const char* xmlFile = 0;
  62. SAX2XMLReader::ValSchemes valScheme = SAX2XMLReader::Val_Auto;
  63. bool doNamespaces = true;
  64. bool doSchema = true;
  65. bool schemaFullChecking = false;
  66. bool doList = false;
  67. bool errorOccurred = false;
  68. bool namespacePrefixes = false;
  69. int argInd;
  70. for (argInd = 1; argInd < argC; ++argInd)
  71. {
  72. // Break out on first parm not starting with a dash
  73. if (argV[argInd][0] != '-')
  74. break;
  75. // Watch for special case help request
  76. if (!strcmp(argV[argInd], "-?"))
  77. {
  78. usage();
  79. cms::concurrency::xercesTerminate();
  80. return 2;
  81. }
  82. else if (!strncmp(argV[argInd], "-v=", 3)
  83. || !strncmp(argV[argInd], "-V=", 3))
  84. {
  85. const char* const parm = &argV[argInd][3];
  86. if (!strcmp(parm, "never"))
  87. valScheme = SAX2XMLReader::Val_Never;
  88. else if (!strcmp(parm, "auto"))
  89. valScheme = SAX2XMLReader::Val_Auto;
  90. else if (!strcmp(parm, "always"))
  91. valScheme = SAX2XMLReader::Val_Always;
  92. else
  93. {
  94. cerr << "Unknown -v= value: " << parm << endl;
  95. cms::concurrency::xercesTerminate();
  96. return 2;
  97. }
  98. }
  99. else if (!strcmp(argV[argInd], "-n")
  100. || !strcmp(argV[argInd], "-N"))
  101. {
  102. doNamespaces = false;
  103. }
  104. else if (!strcmp(argV[argInd], "-s")
  105. || !strcmp(argV[argInd], "-S"))
  106. {
  107. doSchema = false;
  108. }
  109. else if (!strcmp(argV[argInd], "-f")
  110. || !strcmp(argV[argInd], "-F"))
  111. {
  112. schemaFullChecking = true;
  113. }
  114. else if (!strcmp(argV[argInd], "-l")
  115. || !strcmp(argV[argInd], "-L"))
  116. {
  117. doList = true;
  118. }
  119. else if (!strcmp(argV[argInd], "-p")
  120. || !strcmp(argV[argInd], "-P"))
  121. {
  122. namespacePrefixes = true;
  123. }
  124. else if (!strcmp(argV[argInd], "-special:nel"))
  125. {
  126. // turning this on will lead to non-standard compliance behaviour
  127. // it will recognize the unicode character 0x85 as new line character
  128. // instead of regular character as specified in XML 1.0
  129. // do not turn this on unless really necessary
  130. XMLPlatformUtils::recognizeNEL(true);
  131. }
  132. else
  133. {
  134. cerr << "Unknown option '" << argV[argInd]
  135. << "', ignoring it\n" << endl;
  136. }
  137. }
  138. //
  139. // There should be only one and only one parameter left, and that
  140. // should be the file name.
  141. //
  142. if (argInd != argC - 1)
  143. {
  144. usage();
  145. cms::concurrency::xercesTerminate();
  146. return 1;
  147. }
  148. //
  149. // Create a SAX parser object. Then, according to what we were told on
  150. // the command line, set it to validate or not.
  151. //
  152. SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
  153. parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
  154. parser->setFeature(XMLUni::fgXercesSchema, doSchema);
  155. parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
  156. parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, namespacePrefixes);
  157. if (valScheme == SAX2XMLReader::Val_Auto)
  158. {
  159. parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
  160. parser->setFeature(XMLUni::fgXercesDynamic, true);
  161. }
  162. if (valScheme == SAX2XMLReader::Val_Never)
  163. {
  164. parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
  165. }
  166. if (valScheme == SAX2XMLReader::Val_Always)
  167. {
  168. parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
  169. parser->setFeature(XMLUni::fgXercesDynamic, false);
  170. }
  171. //
  172. // Create our SAX handler object and install it on the parser, as the
  173. // document and error handler.
  174. //
  175. SaxToDom handler;
  176. parser->setContentHandler(&handler);
  177. parser->setErrorHandler(&handler);
  178. //
  179. // Get the starting time and kick off the parse of the indicated
  180. // file. Catch any exceptions that might propogate out of it.
  181. //
  182. unsigned long duration;
  183. bool more = true;
  184. ifstream fin;
  185. // the input is a list file
  186. if (doList)
  187. fin.open(argV[argInd]);
  188. while (more)
  189. {
  190. char fURI[1000];
  191. //initialize the array to zeros
  192. memset(fURI,0,sizeof(fURI));
  193. if (doList) {
  194. if (! fin.eof() ) {
  195. fin.getline (fURI, sizeof(fURI));
  196. if (!*fURI)
  197. continue;
  198. else {
  199. xmlFile = fURI;
  200. cerr << "==Parsing== " << xmlFile << endl;
  201. }
  202. }
  203. else
  204. break;
  205. }
  206. else {
  207. xmlFile = argV[argInd];
  208. more = false;
  209. }
  210. //reset error count first
  211. handler.resetErrors();
  212. try
  213. {
  214. const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
  215. cout << "start parsing:" << xmlFile << endl;
  216. parser->parse(xmlFile);
  217. cout << "parsing ended" << endl;
  218. const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
  219. duration = endMillis - startMillis;
  220. }
  221. catch (const XMLException& e)
  222. {
  223. cerr << "\nError during parsing: '" << xmlFile << "'\n"
  224. << "Exception message is: \n"
  225. << StrX(e.getMessage()) << "\n" << endl;
  226. errorOccurred = true;
  227. continue;
  228. }
  229. catch (...)
  230. {
  231. cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
  232. errorOccurred = true;
  233. continue;
  234. }
  235. // Print out the stats that we collected and time taken
  236. if (true && getenv("DOTEST"))
  237. {
  238. TinyDomTest test(handler.dom());
  239. vector<const AttList *> atts;
  240. test.allNodes(NodeName("Box"),atts);
  241. unsigned int i = 0;
  242. for (; i < atts.size(); ++i) {
  243. const AttList & a = *(atts[i]);
  244. AttList::const_iterator it = a.begin();
  245. for (; it != a.end(); ++it) {
  246. cout << it->first.str() << '=' << it->second.str() << ' ';
  247. }
  248. cout << endl;
  249. }
  250. cout << "dom-size=" << handler.dom().size() << endl;
  251. /*
  252. TinyDomWalker walker(handler.dom());
  253. bool go = true;
  254. TagName name("Box");
  255. while (go) {
  256. if (name.sameName(walker.current().first)) {
  257. cout << walker.current().first.str() << endl;
  258. }
  259. go = walker.next();
  260. }
  261. */
  262. }
  263. else
  264. errorOccurred = true;
  265. }
  266. if (doList)
  267. fin.close();
  268. //
  269. // Delete the parser itself. Must be done prior to calling Terminate, below.
  270. //
  271. delete parser;
  272. // And call the termination method
  273. cms::concurrency::xercesTerminate();
  274. if (errorOccurred)
  275. return 4;
  276. else
  277. return 0;
  278. }