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

词法分析

开发平台:

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: SAX2Count.cpp,v $
  58. * Revision 1.24  2002/12/10 13:34:51  tng
  59. * Samples minor update in usage information.
  60. *
  61. * Revision 1.23  2002/11/08 16:18:50  peiyongz
  62. * no message
  63. *
  64. * Revision 1.22  2002/11/07 18:30:42  peiyongz
  65. * command line option for "locale"
  66. *
  67. * Revision 1.21  2002/11/04 14:09:06  tng
  68. * [Bug 14201] use of ios::nocreate breaks build.
  69. *
  70. * Revision 1.20  2002/11/01 22:05:57  tng
  71. * Samples/Test update: Issue error if the list file failed to open.
  72. *
  73. * Revision 1.19  2002/09/27 19:24:57  tng
  74. * Samples Fix: wrong length in memset
  75. *
  76. * Revision 1.18  2002/07/17 18:58:35  tng
  77. * samples update: for testing special encoding purpose.
  78. *
  79. * Revision 1.17  2002/06/17 15:33:05  tng
  80. * Name Xerces features as XMLUni::fgXercesXXXX instead of XMLUni::fgSAX2XercesXXXX so that they can be shared with DOM parser.
  81. *
  82. * Revision 1.16  2002/02/13 16:11:06  knoaman
  83. * Update samples to use SAX2 features/properties constants from XMLUni.
  84. *
  85. * Revision 1.15  2002/02/06 16:36:51  knoaman
  86. * Added a new flag '-p' to SAX2 samples to set the 'namespace-prefixes' feature.
  87. *
  88. * Revision 1.14  2002/02/01 22:38:52  peiyongz
  89. * sane_include
  90. *
  91. * Revision 1.13  2001/10/29 17:02:57  tng
  92. * Fix typo in samples.
  93. *
  94. * Revision 1.12  2001/10/25 15:18:33  tng
  95. * delete the parser before XMLPlatformUtils::Terminate.
  96. *
  97. * Revision 1.11  2001/10/19 19:02:43  tng
  98. * [Bug 3909] return non-zero an exit code when error was encounted.
  99. * And other modification for consistent help display and return code across samples.
  100. *
  101. * Revision 1.10  2001/08/15 12:41:04  tng
  102. * Initialize the fURI array to zeros, in case, some compilers like AIX xlC_r doesn't reset the memory.
  103. *
  104. * Revision 1.9  2001/08/08 12:12:32  tng
  105. * Print the file name only if doList is on.
  106. *
  107. * Revision 1.8  2001/08/03 15:08:17  tng
  108. * close the list file.
  109. *
  110. * Revision 1.7  2001/08/02 17:10:29  tng
  111. * Allow DOMCount/SAXCount/IDOMCount/SAX2Count to take a file that has a list of xml file as input.
  112. *
  113. * Revision 1.6  2001/08/01 19:11:01  tng
  114. * Add full schema constraint checking flag to the samples and the parser.
  115. *
  116. * Revision 1.5  2001/05/11 13:24:56  tng
  117. * Copyright update.
  118. *
  119. * Revision 1.4  2001/05/03 15:59:55  tng
  120. * Schema: samples update with schema
  121. *
  122. * Revision 1.3  2000/08/09 22:46:06  jpolast
  123. * replace occurences of SAXCount with SAX2Count
  124. *
  125. * Revision 1.2  2000/08/09 22:40:15  jpolast
  126. * updates for changes to sax2 core functionality.
  127. *
  128. * Revision 1.1  2000/08/08 17:17:20  jpolast
  129. * initial checkin of SAX2Count
  130. *
  131. *
  132. */
  133. // ---------------------------------------------------------------------------
  134. //  Includes
  135. // ---------------------------------------------------------------------------
  136. #include "SAX2Count.hpp"
  137. #include <xercesc/util/PlatformUtils.hpp>
  138. #include <xercesc/sax2/SAX2XMLReader.hpp>
  139. #include <xercesc/sax2/XMLReaderFactory.hpp>
  140. #include <fstream.h>
  141. // ---------------------------------------------------------------------------
  142. //  Local helper methods
  143. // ---------------------------------------------------------------------------
  144. void usage()
  145. {
  146.     cout << "nUsage:n"
  147.             "    SAX2Count [options] <XML file | List file>nn"
  148.             "This program invokes the SAX2XMLReader, and then prints then"
  149.             "number of elements, attributes, spaces and characters foundn"
  150.             "in each XML file, using SAX2 API.nn"
  151.             "Options:n"
  152.             "    -l          Indicate the input file is a List File that has a list of xml files.n"
  153.             "                Default to off (Input file is an XML file).n"
  154.             "    -v=xxx      Validation scheme [always | never | auto*].n"
  155.             "    -f          Enable full schema constraint checking processing. Defaults to off.n"
  156.             "    -p          Enable namespace-prefixes feature. Defaults to off.n"
  157.             "    -n          Disable namespace processing. Defaults to on.n"
  158.             "                NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.n"
  159.             "    -s          Disable schema processing. Defaults to on.n"
  160.             "                NOTE: THIS IS OPPOSITE FROM OTHER SAMPLES.n"
  161.             "    -locale=ll_CC specify the locale, default: en_US.n"
  162.             "    -?          Show this help.nn"
  163.             "  * = Default if not provided explicitly.n"
  164.          << endl;
  165. }
  166. // ---------------------------------------------------------------------------
  167. //  Program entry point
  168. // ---------------------------------------------------------------------------
  169. int main(int argC, char* argV[])
  170. {
  171.     // Check command line and extract arguments.
  172.     if (argC < 2)
  173.     {
  174.         usage();
  175.         return 1;
  176.     }
  177.     const char*                  xmlFile      = 0;
  178.     SAX2XMLReader::ValSchemes    valScheme    = SAX2XMLReader::Val_Auto;
  179.     bool                         doNamespaces = true;
  180.     bool                         doSchema = true;
  181.     bool                         schemaFullChecking = false;
  182.     bool                         doList = false;
  183.     bool                         errorOccurred = false;
  184.     bool                         namespacePrefixes = false;
  185.     bool                         recognizeNEL = false;
  186.     char                         localeStr[64];
  187.     memset(localeStr, 0, sizeof localeStr);
  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.             return 2;
  199.         }
  200.          else if (!strncmp(argV[argInd], "-v=", 3)
  201.               ||  !strncmp(argV[argInd], "-V=", 3))
  202.         {
  203.             const char* const parm = &argV[argInd][3];
  204.             if (!strcmp(parm, "never"))
  205.                 valScheme = SAX2XMLReader::Val_Never;
  206.             else if (!strcmp(parm, "auto"))
  207.                 valScheme = SAX2XMLReader::Val_Auto;
  208.             else if (!strcmp(parm, "always"))
  209.                 valScheme = SAX2XMLReader::Val_Always;
  210.             else
  211.             {
  212.                 cerr << "Unknown -v= value: " << parm << endl;
  213.                 return 2;
  214.             }
  215.         }
  216.          else if (!strcmp(argV[argInd], "-n")
  217.               ||  !strcmp(argV[argInd], "-N"))
  218.         {
  219.             doNamespaces = false;
  220.         }
  221.          else if (!strcmp(argV[argInd], "-s")
  222.               ||  !strcmp(argV[argInd], "-S"))
  223.         {
  224.             doSchema = false;
  225.         }
  226.          else if (!strcmp(argV[argInd], "-f")
  227.               ||  !strcmp(argV[argInd], "-F"))
  228.         {
  229.             schemaFullChecking = true;
  230.         }
  231.          else if (!strcmp(argV[argInd], "-l")
  232.               ||  !strcmp(argV[argInd], "-L"))
  233.         {
  234.             doList = true;
  235.         }
  236.          else if (!strcmp(argV[argInd], "-p")
  237.               ||  !strcmp(argV[argInd], "-P"))
  238.         {
  239.             namespacePrefixes = true;
  240.         }
  241.          else if (!strcmp(argV[argInd], "-special:nel"))
  242.         {
  243.             // turning this on will lead to non-standard compliance behaviour
  244.             // it will recognize the unicode character 0x85 as new line character
  245.             // instead of regular character as specified in XML 1.0
  246.             // do not turn this on unless really necessary
  247.              recognizeNEL = true;
  248.         }
  249.          else if (!strncmp(argV[argInd], "-locale=", 8))
  250.         {
  251.              // Get out the end of line
  252.              strcpy(localeStr, &(argV[argInd][8]));
  253.         }
  254.         else
  255.         {
  256.             cerr << "Unknown option '" << argV[argInd]
  257.                 << "', ignoring itn" << endl;
  258.         }
  259.     }
  260.     //
  261.     //  There should be only one and only one parameter left, and that
  262.     //  should be the file name.
  263.     //
  264.     if (argInd != argC - 1)
  265.     {
  266.         usage();
  267.         return 1;
  268.     }
  269.     // Initialize the XML4C2 system
  270.     try
  271.     {
  272.         if (strlen(localeStr))
  273.         {
  274.             XMLPlatformUtils::Initialize(localeStr);
  275.         }
  276.         else
  277.         {
  278.             XMLPlatformUtils::Initialize();
  279.         }
  280.         if (recognizeNEL)
  281.         {
  282.             XMLPlatformUtils::recognizeNEL(recognizeNEL);
  283.         }
  284.     }
  285.     catch (const XMLException& toCatch)
  286.     {
  287.         cerr << "Error during initialization! Message:n"
  288.             << StrX(toCatch.getMessage()) << endl;
  289.         return 1;
  290.     }
  291.     //
  292.     //  Create a SAX parser object. Then, according to what we were told on
  293.     //  the command line, set it to validate or not.
  294.     //
  295.     SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
  296.     parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, doNamespaces);
  297.     parser->setFeature(XMLUni::fgXercesSchema, doSchema);
  298.     parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);
  299.     parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, namespacePrefixes);
  300.     if (valScheme == SAX2XMLReader::Val_Auto)
  301.     {
  302.         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
  303.         parser->setFeature(XMLUni::fgXercesDynamic, true);
  304.     }
  305.     if (valScheme == SAX2XMLReader::Val_Never)
  306.     {
  307.         parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
  308.     }
  309.     if (valScheme == SAX2XMLReader::Val_Always)
  310.     {
  311.         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
  312.         parser->setFeature(XMLUni::fgXercesDynamic, false);
  313.     }
  314.     //
  315.     //  Create our SAX handler object and install it on the parser, as the
  316.     //  document and error handler.
  317.     //
  318.     SAX2CountHandlers handler;
  319.     parser->setContentHandler(&handler);
  320.     parser->setErrorHandler(&handler);
  321.     //
  322.     //  Get the starting time and kick off the parse of the indicated
  323.     //  file. Catch any exceptions that might propogate out of it.
  324.     //
  325.     unsigned long duration;
  326.     bool more = true;
  327.     ifstream fin;
  328.     // the input is a list file
  329.     if (doList)
  330.         fin.open(argV[argInd]);
  331.     if (fin.fail()) {
  332.         cerr <<"Cannot open the list file: " << argV[argInd] << endl;
  333.         return 2;
  334.     }
  335.     while (more)
  336.     {
  337.         char fURI[1000];
  338.         //initialize the array to zeros
  339.         memset(fURI,0,sizeof(fURI));
  340.         if (doList) {
  341.             if (! fin.eof() ) {
  342.                 fin.getline (fURI, sizeof(fURI));
  343.                 if (!*fURI)
  344.                     continue;
  345.                 else {
  346.                     xmlFile = fURI;
  347.                     cerr << "==Parsing== " << xmlFile << endl;
  348.                 }
  349.             }
  350.             else
  351.                 break;
  352.         }
  353.         else {
  354.             xmlFile = argV[argInd];
  355.             more = false;
  356.         }
  357.         //reset error count first
  358.         handler.resetErrors();
  359.         try
  360.         {
  361.             const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
  362.             parser->parse(xmlFile);
  363.             const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
  364.             duration = endMillis - startMillis;
  365.         }
  366.         catch (const XMLException& e)
  367.         {
  368.             cerr << "nError during parsing: '" << xmlFile << "'n"
  369.                 << "Exception message is:  n"
  370.                 << StrX(e.getMessage()) << "n" << endl;
  371.             errorOccurred = true;
  372.             continue;
  373.         }
  374.         catch (...)
  375.         {
  376.             cerr << "nUnexpected exception during parsing: '" << xmlFile << "'n";
  377.             errorOccurred = true;
  378.             continue;
  379.         }
  380.         // Print out the stats that we collected and time taken
  381.         if (!handler.getSawErrors())
  382.         {
  383.             cout << xmlFile << ": " << duration << " ms ("
  384.                 << handler.getElementCount() << " elems, "
  385.                 << handler.getAttrCount() << " attrs, "
  386.                 << handler.getSpaceCount() << " spaces, "
  387.                 << handler.getCharacterCount() << " chars)" << endl;
  388.         }
  389.         else
  390.             errorOccurred = true;
  391.     }
  392.     if (doList)
  393.         fin.close();
  394.     //
  395.     //  Delete the parser itself.  Must be done prior to calling Terminate, below.
  396.     //
  397.     delete parser;
  398.     // And call the termination method
  399.     XMLPlatformUtils::Terminate();
  400.     if (errorOccurred)
  401.         return 4;
  402.     else
  403.         return 0;
  404. }