SAXCount.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:12k
源码类别:

xml/soap/webservice

开发平台:

C/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.20  2001/11/13 13:22:35  tng
  59. * SAXCount fix: restore previous feature to accept multiple input files.
  60. *
  61. * Revision 1.19  2001/10/29 17:02:57  tng
  62. * Fix typo in samples.
  63. *
  64. * Revision 1.18  2001/10/25 15:18:33  tng
  65. * delete the parser before XMLPlatformUtils::Terminate.
  66. *
  67. * Revision 1.17  2001/10/19 19:02:43  tng
  68. * [Bug 3909] return non-zero an exit code when error was encounted.
  69. * And other modification for consistent help display and return code across samples.
  70. *
  71. * Revision 1.16  2001/08/15 12:41:04  tng
  72. * Initialize the fURI array to zeros, in case, some compilers like AIX xlC_r doesn't reset the memory.
  73. *
  74. * Revision 1.15  2001/08/08 12:12:32  tng
  75. * Print the file name only if doList is on.
  76. *
  77. * Revision 1.14  2001/08/03 15:08:17  tng
  78. * close the list file.
  79. *
  80. * Revision 1.13  2001/08/02 17:10:29  tng
  81. * Allow DOMCount/SAXCount/IDOMCount/SAX2Count to take a file that has a list of xml file as input.
  82. *
  83. * Revision 1.12  2001/08/01 19:11:01  tng
  84. * Add full schema constraint checking flag to the samples and the parser.
  85. *
  86. * Revision 1.11  2001/05/11 13:24:57  tng
  87. * Copyright update.
  88. *
  89. * Revision 1.10  2001/05/03 16:00:12  tng
  90. * Schema: samples update with schema
  91. *
  92. * Revision 1.9  2000/10/19 23:52:41  andyh
  93. * SAXCount: Allow multiple files on command line
  94. *
  95. * Revision 1.8  2000/06/16 20:25:38  rahulj
  96. * Add the -v=always option to force validation checking. Need this
  97. * option for running the conformance tests.
  98. *
  99. * Revision 1.7  2000/05/31 18:39:59  rahulj
  100. * 'Auto' validation is the default processing mode.
  101. *
  102. * Revision 1.6  2000/05/09 00:22:29  andyh
  103. * Memory Cleanup.  XMLPlatformUtils::Terminate() deletes all lazily
  104. * allocated memory; memory leak checking tools will no longer report
  105. * that leaks exist.  (DOM GetElementsByTagID temporarily removed
  106. * as part of this.)
  107. *
  108. * Revision 1.5  2000/03/03 01:29:31  roddey
  109. * Added a scanReset()/parseReset() method to the scanner and
  110. * parsers, to allow for reset after early exit from a progressive parse.
  111. * Added calls to new Terminate() call to all of the samples. Improved
  112. * documentation in SAX and DOM parsers.
  113. *
  114. * Revision 1.4  2000/03/02 19:53:47  roddey
  115. * This checkin includes many changes done while waiting for the
  116. * 1.1.0 code to be finished. I can't list them all here, but a list is
  117. * available elsewhere.
  118. *
  119. * Revision 1.3  2000/02/11 02:39:10  abagchi
  120. * Removed StrX::transcode
  121. *
  122. * Revision 1.2  2000/02/06 07:47:23  rahulj
  123. * Year 2K copyright swat.
  124. *
  125. * Revision 1.1.1.1  1999/11/09 01:09:30  twl
  126. * Initial checkin
  127. *
  128. * Revision 1.7  1999/11/08 20:43:40  rahul
  129. * Swat for adding in Product name and CVS comment log variable.
  130. *
  131. */
  132. // ---------------------------------------------------------------------------
  133. //  Includes
  134. // ---------------------------------------------------------------------------
  135. #include "SAXCount.hpp"
  136. #include <fstream.h>
  137. // ---------------------------------------------------------------------------
  138. //  Local helper methods
  139. // ---------------------------------------------------------------------------
  140. void usage()
  141. {
  142.     cout << "nUsage:n"
  143.             "    SAXCount [options] <XML file | List file>nn"
  144.             "This program invokes the SAX Parser, and then prints then"
  145.             "number of elements, attributes, spaces and characters foundn"
  146.             "in each XML file, using SAX API.nn"
  147.             "Options:n"
  148.             "    -l          Indicate the input file is a List File that has a list of xml files.n"
  149.             "                Default to off (Input file is an XML file).n"
  150.             "    -v=xxx      Validation scheme [always | never | auto*].n"
  151.             "    -n          Enable namespace processing. Defaults to off.n"
  152.             "    -s          Enable schema processing. Defaults to off.n"
  153.             "    -f          Enable full schema constraint checking. Defaults to off.n"
  154.       "    -?          Show this help.nn"
  155.             "  * = Default if not provided explicitly.n"
  156.          << endl;
  157. }
  158. // ---------------------------------------------------------------------------
  159. //  Program entry point
  160. // ---------------------------------------------------------------------------
  161. int main(int argC, char* argV[])
  162. {
  163.     // Initialize the XML4C2 system
  164.     try
  165.     {
  166.         XMLPlatformUtils::Initialize();
  167.     }
  168.     catch (const XMLException& toCatch)
  169.     {
  170.         cerr << "Error during initialization! Message:n"
  171.             << StrX(toCatch.getMessage()) << endl;
  172.         return 1;
  173.     }
  174.     // Check command line and extract arguments.
  175.     if (argC < 2)
  176.     {
  177.         usage();
  178.         XMLPlatformUtils::Terminate();
  179.         return 1;
  180.     }
  181.     const char*              xmlFile = 0;
  182.     SAXParser::ValSchemes    valScheme = SAXParser::Val_Auto;
  183.     bool                     doNamespaces       = false;
  184.     bool                     doSchema           = false;
  185.     bool                     schemaFullChecking = false;
  186.     bool                     doList = false;
  187.     bool                     errorOccurred = false;
  188.     int argInd;
  189.     for (argInd = 1; argInd < argC; argInd++)
  190.     {
  191.         // Break out on first parm not starting with a dash
  192.         if (argV[argInd][0] != '-')
  193.             break;
  194.         // Watch for special case help request
  195.         if (!strcmp(argV[argInd], "-?"))
  196.         {
  197.             usage();
  198.             XMLPlatformUtils::Terminate();
  199.             return 2;
  200.         }
  201.          else if (!strncmp(argV[argInd], "-v=", 3)
  202.               ||  !strncmp(argV[argInd], "-V=", 3))
  203.         {
  204.             const char* const parm = &argV[argInd][3];
  205.             if (!strcmp(parm, "never"))
  206.                 valScheme = SAXParser::Val_Never;
  207.             else if (!strcmp(parm, "auto"))
  208.                 valScheme = SAXParser::Val_Auto;
  209.             else if (!strcmp(parm, "always"))
  210.                 valScheme = SAXParser::Val_Always;
  211.             else
  212.             {
  213.                 cerr << "Unknown -v= value: " << parm << endl;
  214.                 XMLPlatformUtils::Terminate();
  215.                 return 2;
  216.             }
  217.         }
  218.          else if (!strcmp(argV[argInd], "-n")
  219.               ||  !strcmp(argV[argInd], "-N"))
  220.         {
  221.             doNamespaces = true;
  222.         }
  223.          else if (!strcmp(argV[argInd], "-s")
  224.               ||  !strcmp(argV[argInd], "-S"))
  225.         {
  226.             doSchema = true;
  227.         }
  228.          else if (!strcmp(argV[argInd], "-f")
  229.               ||  !strcmp(argV[argInd], "-F"))
  230.         {
  231.             schemaFullChecking = true;
  232.         }
  233.          else if (!strcmp(argV[argInd], "-l")
  234.               ||  !strcmp(argV[argInd], "-L"))
  235.         {
  236.             doList = true;
  237.         }
  238.         else
  239.         {
  240.             cerr << "Unknown option '" << argV[argInd]
  241.                 << "', ignoring itn" << endl;
  242.         }
  243.     }
  244.     //
  245.     //  There should at least one parameter left, and that
  246.     //  should be the file name(s).
  247.     //
  248.     if (argInd == argC)
  249.     {
  250.         usage();
  251.         XMLPlatformUtils::Terminate();
  252.         return 1;
  253.     }
  254.     //
  255.     //  Create a SAX parser object. Then, according to what we were told on
  256.     //  the command line, set it to validate or not.
  257.     //
  258.     SAXParser* parser = new SAXParser;
  259.     parser->setValidationScheme(valScheme);
  260.     parser->setDoNamespaces(doNamespaces);
  261.     parser->setDoSchema(doSchema);
  262.     parser->setValidationSchemaFullChecking(schemaFullChecking);
  263.     //
  264.     //  Create our SAX handler object and install it on the parser, as the
  265.     //  document and error handler.
  266.     //
  267.     SAXCountHandlers handler;
  268.     parser->setDocumentHandler(&handler);
  269.     parser->setErrorHandler(&handler);
  270.     //
  271.     //  Get the starting time and kick off the parse of the indicated
  272.     //  file. Catch any exceptions that might propogate out of it.
  273.     //
  274.     unsigned long duration;
  275.     ifstream fin;
  276.     // the input is a list file
  277.     if (doList)
  278.         fin.open(argV[argInd]);
  279.     while (true)
  280.     {
  281.         char fURI[1000];
  282.         //initialize the array to zeros
  283.         memset(fURI,0,sizeof(fURI));
  284.         if (doList) {
  285.             if (! fin.eof() ) {
  286.                 fin.getline (fURI, sizeof(fURI));
  287.                 if (!*fURI)
  288.                     continue;
  289.                 else {
  290.                     xmlFile = fURI;
  291.                     cerr << "==Parsing== " << xmlFile << endl;
  292.                 }
  293.             }
  294.             else
  295.                 break;
  296.         }
  297.         else {
  298.             if (argInd < argC)
  299.             {
  300.                  xmlFile = argV[argInd];
  301.                  argInd++;
  302.             }
  303.             else
  304.                 break;
  305.         }
  306.         //reset error count first
  307.         handler.resetErrors();
  308.         try
  309.         {
  310.             const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
  311.             parser->parse(xmlFile);
  312.             const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
  313.             duration = endMillis - startMillis;
  314.         }
  315.         catch (const XMLException& e)
  316.         {
  317.             cerr << "nError during parsing: '" << xmlFile << "'n"
  318.                 << "Exception message is:  n"
  319.                 << StrX(e.getMessage()) << "n" << endl;
  320.             errorOccurred = true;
  321.             continue;
  322.         }
  323.         catch (...)
  324.         {
  325.             cerr << "nUnexpected exception during parsing: '" << xmlFile << "'n";
  326.             errorOccurred = true;
  327.             continue;
  328.         }
  329.         // Print out the stats that we collected and time taken
  330.         if (!handler.getSawErrors())
  331.         {
  332.             cout << xmlFile << ": " << duration << " ms ("
  333.                 << handler.getElementCount() << " elems, "
  334.                 << handler.getAttrCount() << " attrs, "
  335.                 << handler.getSpaceCount() << " spaces, "
  336.                 << handler.getCharacterCount() << " chars)" << endl;
  337.         }
  338.         else
  339.             errorOccurred = true;
  340.     }
  341.     if (doList)
  342.         fin.close();
  343.     //
  344.     //  Delete the parser itself.  Must be done prior to calling Terminate, below.
  345.     //
  346.     delete parser;
  347.     // And call the termination method
  348.     XMLPlatformUtils::Terminate();
  349.     if (errorOccurred)
  350.         return 4;
  351.     else
  352.         return 0;
  353. }