SAXCount.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:14k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. *    notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. *    notice, this list of conditions and the following disclaimer in
  16. *    the documentation and/or other materials provided with the
  17. *    distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution,
  20. *    if any, must include the following acknowledgment:
  21. *       "This product includes software developed by the
  22. *        Apache Software Foundation (http://www.apache.org/)."
  23. *    Alternately, this acknowledgment may appear in the software itself,
  24. *    if and wherever such third-party acknowledgments normally appear.
  25. *
  26. * 4. The names "Xerces" and "Apache Software Foundation" must
  27. *    not be used to endorse or promote products derived from this
  28. *    software without prior written permission. For written
  29. *    permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache",
  32. *    nor may "Apache" appear in their name, without prior written
  33. *    permission of the Apache Software Foundation.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation, and was
  51. * originally based on software copyright (c) 1999, International
  52. * Business Machines, Inc., http://www.ibm.com .  For more information
  53. * on the Apache Software Foundation, please see
  54. * <http://www.apache.org/>.
  55. */
  56. /*
  57. * $Log: SAXCount.cpp,v $
  58. * Revision 1.27  2002/12/10 13:34:42  tng
  59. * Samples minor update in usage information.
  60. *
  61. * Revision 1.26  2002/11/08 16:19:05  peiyongz
  62. * no message
  63. *
  64. * Revision 1.25  2002/11/07 18:31:04  peiyongz
  65. * command line option for "locale"
  66. *
  67. * Revision 1.24  2002/11/04 14:09:16  tng
  68. * [Bug 14201] use of ios::nocreate breaks build.
  69. *
  70. * Revision 1.23  2002/11/01 22:05:44  tng
  71. * Samples/Test update: Issue error if the list file failed to open.
  72. *
  73. * Revision 1.22  2002/09/27 19:25:10  tng
  74. * Samples Fix: wrong length in memset
  75. *
  76. * Revision 1.21  2002/07/17 18:58:36  tng
  77. * samples update: for testing special encoding purpose.
  78. *
  79. * Revision 1.20  2001/11/13 13:22:35  tng
  80. * SAXCount fix: restore previous feature to accept multiple input files.
  81. *
  82. * Revision 1.19  2001/10/29 17:02:57  tng
  83. * Fix typo in samples.
  84. *
  85. * Revision 1.18  2001/10/25 15:18:33  tng
  86. * delete the parser before XMLPlatformUtils::Terminate.
  87. *
  88. * Revision 1.17  2001/10/19 19:02:43  tng
  89. * [Bug 3909] return non-zero an exit code when error was encounted.
  90. * And other modification for consistent help display and return code across samples.
  91. *
  92. * Revision 1.16  2001/08/15 12:41:04  tng
  93. * Initialize the fURI array to zeros, in case, some compilers like AIX xlC_r doesn't reset the memory.
  94. *
  95. * Revision 1.15  2001/08/08 12:12:32  tng
  96. * Print the file name only if doList is on.
  97. *
  98. * Revision 1.14  2001/08/03 15:08:17  tng
  99. * close the list file.
  100. *
  101. * Revision 1.13  2001/08/02 17:10:29  tng
  102. * Allow DOMCount/SAXCount/IDOMCount/SAX2Count to take a file that has a list of xml file as input.
  103. *
  104. * Revision 1.12  2001/08/01 19:11:01  tng
  105. * Add full schema constraint checking flag to the samples and the parser.
  106. *
  107. * Revision 1.11  2001/05/11 13:24:57  tng
  108. * Copyright update.
  109. *
  110. * Revision 1.10  2001/05/03 16:00:12  tng
  111. * Schema: samples update with schema
  112. *
  113. * Revision 1.9  2000/10/19 23:52:41  andyh
  114. * SAXCount: Allow multiple files on command line
  115. *
  116. * Revision 1.8  2000/06/16 20:25:38  rahulj
  117. * Add the -v=always option to force validation checking. Need this
  118. * option for running the conformance tests.
  119. *
  120. * Revision 1.7  2000/05/31 18:39:59  rahulj
  121. * 'Auto' validation is the default processing mode.
  122. *
  123. * Revision 1.6  2000/05/09 00:22:29  andyh
  124. * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
  125. * allocated memory; memory leak checking tools will no longer report
  126. * that leaks exist.  (DOM GetElementsByTagID temporarily removed
  127. * as part of this.)
  128. *
  129. * Revision 1.5  2000/03/03 01:29:31  roddey
  130. * Added a scanReset()/parseReset() method to the scanner and
  131. * parsers, to allow for reset after early exit from a progressive parse.
  132. * Added calls to new Terminate() call to all of the samples. Improved
  133. * documentation in SAX and DOM parsers.
  134. *
  135. * Revision 1.4  2000/03/02 19:53:47  roddey
  136. * This checkin includes many changes done while waiting for the
  137. * 1.1.0 code to be finished. I can't list them all here, but a list is
  138. * available elsewhere.
  139. *
  140. * Revision 1.3  2000/02/11 02:39:10  abagchi
  141. * Removed StrX::transcode
  142. *
  143. * Revision 1.2  2000/02/06 07:47:23  rahulj
  144. * Year 2K copyright swat.
  145. *
  146. * Revision 1.1.1.1  1999/11/09 01:09:30  twl
  147. * Initial checkin
  148. *
  149. * Revision 1.7  1999/11/08 20:43:40  rahul
  150. * Swat for adding in Product name and CVS comment log variable.
  151. *
  152. */
  153. // ---------------------------------------------------------------------------
  154. //  Includes
  155. // ---------------------------------------------------------------------------
  156. #include "SAXCount.hpp"
  157. #include <fstream.h>
  158. // ---------------------------------------------------------------------------
  159. //  Local helper methods
  160. // ---------------------------------------------------------------------------
  161. void usage()
  162. {
  163.     cout << "nUsage:n"
  164.             "    SAXCount [options] <XML file | List file>nn"
  165.             "This program invokes the SAX Parser, and then prints then"
  166.             "number of elements, attributes, spaces and characters foundn"
  167.             "in each XML file, using SAX API.nn"
  168.             "Options:n"
  169.             "    -l          Indicate the input file is a List File that has a list of xml files.n"
  170.             "                Default to off (Input file is an XML file).n"
  171.             "    -v=xxx      Validation scheme [always | never | auto*].n"
  172.             "    -n          Enable namespace processing. Defaults to off.n"
  173.             "    -s          Enable schema processing. Defaults to off.n"
  174.             "    -f          Enable full schema constraint checking. Defaults to off.n"
  175.             "    -locale=ll_CC specify the locale, default: en_US.n"
  176.     "    -?          Show this help.nn"
  177.             "  * = Default if not provided explicitly.n"
  178.          << endl;
  179. }
  180. // ---------------------------------------------------------------------------
  181. //  Program entry point
  182. // ---------------------------------------------------------------------------
  183. int main(int argC, char* argV[])
  184. {
  185.     // Check command line and extract arguments.
  186.     if (argC < 2)
  187.     {
  188.         usage();
  189.         return 1;
  190.     }
  191.     const char*              xmlFile = 0;
  192.     SAXParser::ValSchemes    valScheme = SAXParser::Val_Auto;
  193.     bool                     doNamespaces       = false;
  194.     bool                     doSchema           = false;
  195.     bool                     schemaFullChecking = false;
  196.     bool                     doList = false;
  197.     bool                     errorOccurred = false;
  198.     bool                     recognizeNEL = false;
  199.     char                     localeStr[64];
  200.     memset(localeStr, 0, sizeof localeStr);
  201.     int argInd;
  202.     for (argInd = 1; argInd < argC; argInd++)
  203.     {
  204.         // Break out on first parm not starting with a dash
  205.         if (argV[argInd][0] != '-')
  206.             break;
  207.         // Watch for special case help request
  208.         if (!strcmp(argV[argInd], "-?"))
  209.         {
  210.             usage();
  211.             return 2;
  212.         }
  213.          else if (!strncmp(argV[argInd], "-v=", 3)
  214.               ||  !strncmp(argV[argInd], "-V=", 3))
  215.         {
  216.             const char* const parm = &argV[argInd][3];
  217.             if (!strcmp(parm, "never"))
  218.                 valScheme = SAXParser::Val_Never;
  219.             else if (!strcmp(parm, "auto"))
  220.                 valScheme = SAXParser::Val_Auto;
  221.             else if (!strcmp(parm, "always"))
  222.                 valScheme = SAXParser::Val_Always;
  223.             else
  224.             {
  225.                 cerr << "Unknown -v= value: " << parm << endl;
  226.                 return 2;
  227.             }
  228.         }
  229.          else if (!strcmp(argV[argInd], "-n")
  230.               ||  !strcmp(argV[argInd], "-N"))
  231.         {
  232.             doNamespaces = true;
  233.         }
  234.          else if (!strcmp(argV[argInd], "-s")
  235.               ||  !strcmp(argV[argInd], "-S"))
  236.         {
  237.             doSchema = true;
  238.         }
  239.          else if (!strcmp(argV[argInd], "-f")
  240.               ||  !strcmp(argV[argInd], "-F"))
  241.         {
  242.             schemaFullChecking = true;
  243.         }
  244.          else if (!strcmp(argV[argInd], "-l")
  245.               ||  !strcmp(argV[argInd], "-L"))
  246.         {
  247.             doList = true;
  248.         }
  249.          else if (!strcmp(argV[argInd], "-special:nel"))
  250.         {
  251.             // turning this on will lead to non-standard compliance behaviour
  252.             // it will recognize the unicode character 0x85 as new line character
  253.             // instead of regular character as specified in XML 1.0
  254.             // do not turn this on unless really necessary
  255.              recognizeNEL = true;
  256.         }
  257.          else if (!strncmp(argV[argInd], "-locale=", 8))
  258.         {
  259.              // Get out the end of line
  260.              strcpy(localeStr, &(argV[argInd][8]));
  261.         }
  262.         else
  263.         {
  264.             cerr << "Unknown option '" << argV[argInd]
  265.                 << "', ignoring itn" << endl;
  266.         }
  267.     }
  268.     //
  269.     //  There should at least one parameter left, and that
  270.     //  should be the file name(s).
  271.     //
  272.     if (argInd == argC)
  273.     {
  274.         usage();
  275.         return 1;
  276.     }
  277.     // Initialize the XML4C2 system
  278.     try
  279.     {
  280.         if (strlen(localeStr))
  281.         {
  282.             XMLPlatformUtils::Initialize(localeStr);
  283.         }
  284.         else
  285.         {
  286.             XMLPlatformUtils::Initialize();
  287.         }
  288.         if (recognizeNEL)
  289.         {
  290.             XMLPlatformUtils::recognizeNEL(recognizeNEL);
  291.         }
  292.     }
  293.     catch (const XMLException& toCatch)
  294.     {
  295.         cerr << "Error during initialization! Message:n"
  296.             << StrX(toCatch.getMessage()) << endl;
  297.         return 1;
  298.     }
  299.     //
  300.     //  Create a SAX parser object. Then, according to what we were told on
  301.     //  the command line, set it to validate or not.
  302.     //
  303.     SAXParser* parser = new SAXParser;
  304.     parser->setValidationScheme(valScheme);
  305.     parser->setDoNamespaces(doNamespaces);
  306.     parser->setDoSchema(doSchema);
  307.     parser->setValidationSchemaFullChecking(schemaFullChecking);
  308.     //
  309.     //  Create our SAX handler object and install it on the parser, as the
  310.     //  document and error handler.
  311.     //
  312.     SAXCountHandlers handler;
  313.     parser->setDocumentHandler(&handler);
  314.     parser->setErrorHandler(&handler);
  315.     //
  316.     //  Get the starting time and kick off the parse of the indicated
  317.     //  file. Catch any exceptions that might propogate out of it.
  318.     //
  319.     unsigned long duration;
  320.     ifstream fin;
  321.     // the input is a list file
  322.     if (doList)
  323.         fin.open(argV[argInd]);
  324.     if (fin.fail()) {
  325.         cerr <<"Cannot open the list file: " << argV[argInd] << endl;
  326.         return 2;
  327.     }
  328.     while (true)
  329.     {
  330.         char fURI[1000];
  331.         //initialize the array to zeros
  332.         memset(fURI,0,sizeof(fURI));
  333.         if (doList) {
  334.             if (! fin.eof() ) {
  335.                 fin.getline (fURI, sizeof(fURI));
  336.                 if (!*fURI)
  337.                     continue;
  338.                 else {
  339.                     xmlFile = fURI;
  340.                     cerr << "==Parsing== " << xmlFile << endl;
  341.                 }
  342.             }
  343.             else
  344.                 break;
  345.         }
  346.         else {
  347.             if (argInd < argC)
  348.             {
  349.                  xmlFile = argV[argInd];
  350.                  argInd++;
  351.             }
  352.             else
  353.                 break;
  354.         }
  355.         //reset error count first
  356.         handler.resetErrors();
  357.         try
  358.         {
  359.             const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
  360.             parser->parse(xmlFile);
  361.             const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
  362.             duration = endMillis - startMillis;
  363.         }
  364.         catch (const XMLException& e)
  365.         {
  366.             cerr << "nError during parsing: '" << xmlFile << "'n"
  367.                 << "Exception message is:  n"
  368.                 << StrX(e.getMessage()) << "n" << endl;
  369.             errorOccurred = true;
  370.             continue;
  371.         }
  372.         catch (...)
  373.         {
  374.             cerr << "nUnexpected exception during parsing: '" << xmlFile << "'n";
  375.             errorOccurred = true;
  376.             continue;
  377.         }
  378.         // Print out the stats that we collected and time taken
  379.         if (!handler.getSawErrors())
  380.         {
  381.             cout << xmlFile << ": " << duration << " ms ("
  382.                 << handler.getElementCount() << " elems, "
  383.                 << handler.getAttrCount() << " attrs, "
  384.                 << handler.getSpaceCount() << " spaces, "
  385.                 << handler.getCharacterCount() << " chars)" << endl;
  386.         }
  387.         else
  388.             errorOccurred = true;
  389.     }
  390.     if (doList)
  391.         fin.close();
  392.     //
  393.     //  Delete the parser itself.  Must be done prior to calling Terminate, below.
  394.     //
  395.     delete parser;
  396.     // And call the termination method
  397.     XMLPlatformUtils::Terminate();
  398.     if (errorOccurred)
  399.         return 4;
  400.     else
  401.         return 0;
  402. }