PParse.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: PParse.cpp,v $
  58.  * Revision 1.14  2002/04/17 20:18:08  tng
  59.  * [Bug 7493] The word "occured" is misspelled and it is a global error.
  60.  *
  61.  * Revision 1.13  2002/02/01 22:37:38  peiyongz
  62.  * sane_include
  63.  *
  64.  * Revision 1.12  2001/10/25 15:18:33  tng
  65.  * delete the parser before XMLPlatformUtils::Terminate.
  66.  *
  67.  * Revision 1.11  2001/10/19 18:52:04  tng
  68.  * Since PParse can take any XML file as input file, it shouldn't hardcode to expect 16 elements.
  69.  * Change it to work similar to SAXCount which just prints the number of elements, characters, attributes ... etc.
  70.  * And other modification for consistent help display and return code across samples.
  71.  *
  72.  * Revision 1.10  2001/08/01 19:11:01  tng
  73.  * Add full schema constraint checking flag to the samples and the parser.
  74.  *
  75.  * Revision 1.9  2001/05/11 13:24:55  tng
  76.  * Copyright update.
  77.  *
  78.  * Revision 1.8  2001/05/03 15:59:48  tng
  79.  * Schema: samples update with schema
  80.  *
  81.  * Revision 1.7  2000/06/20 02:23:08  rahulj
  82.  * Help message added by Joe Polastre.
  83.  *
  84.  * Revision 1.6  2000/03/03 01:29:31  roddey
  85.  * Added a scanReset()/parseReset() method to the scanner and
  86.  * parsers, to allow for reset after early exit from a progressive parse.
  87.  * Added calls to new Terminate() call to all of the samples. Improved
  88.  * documentation in SAX and DOM parsers.
  89.  *
  90.  * Revision 1.5  2000/03/02 19:53:44  roddey
  91.  * This checkin includes many changes done while waiting for the
  92.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  93.  * available elsewhere.
  94.  *
  95.  * Revision 1.4  2000/02/11 02:37:48  abagchi
  96.  * Removed StrX::transcode
  97.  *
  98.  * Revision 1.3  2000/02/06 07:47:20  rahulj
  99.  * Year 2K copyright swat.
  100.  *
  101.  * Revision 1.2  2000/01/12 00:27:00  roddey
  102.  * Updates to work with the new URL and input source scheme.
  103.  *
  104.  * Revision 1.1.1.1  1999/11/09 01:09:45  twl
  105.  * Initial checkin
  106.  *
  107.  * Revision 1.5  1999/11/08 20:43:38  rahul
  108.  * Swat for adding in Product name and CVS comment log variable.
  109.  *
  110.  */
  111. // ---------------------------------------------------------------------------
  112. //  This sample program demonstrates the progressive parse capabilities of
  113. //  the parser system. It allows you to do a scanFirst() call followed by
  114. //  a loop which calls scanNext(). You can drop out when you've found what
  115. //  ever it is you want. In our little test, our event handler looks for
  116. //  16 new elements then sets a flag to indicate its found what it wants.
  117. //  At that point, our progressive parse loop below exits.
  118. //
  119. //  The parameters are:
  120. //
  121. //      [-?]            - Show usage and exit
  122. //      [-v=xxx]        - Validation scheme [always | never | auto*]
  123. //      [-n]            - Enable namespace processing
  124. //      [-s]            - Enable schema processing
  125. //      [-f]            - Enable full schema constraint checking
  126. //      filename        - The path to the XML file to parse
  127. //
  128. //  * = Default if not provided explicitly
  129. //  These are non-case sensitive
  130. // ---------------------------------------------------------------------------
  131. // ---------------------------------------------------------------------------
  132. //  Includes
  133. // ---------------------------------------------------------------------------
  134. #include <xercesc/util/PlatformUtils.hpp>
  135. #include <xercesc/framework/XMLPScanToken.hpp>
  136. #include <xercesc/parsers/SAXParser.hpp>
  137. #include "PParse.hpp"
  138. // ---------------------------------------------------------------------------
  139. //  Local data
  140. //
  141. //  xmlFile
  142. //      The path to the file to parser. Set via command line.
  143. //
  144. //  doNamespaces
  145. //      Indicates whether namespace processing should be done.
  146. //
  147. //  doSchema
  148. //      Indicates whether schema processing should be done.
  149. //
  150. //  schemaFullChecking
  151. //      Indicates whether full schema constraint checking should be done.
  152. //
  153. //  valScheme
  154. //      Indicates what validation scheme to use. It defaults to 'auto', but
  155. //      can be set via the -v= command.
  156. // ---------------------------------------------------------------------------
  157. static char*  xmlFile         = 0;
  158. static bool     doNamespaces       = false;
  159. static bool     doSchema           = false;
  160. static bool     schemaFullChecking = false;
  161. static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
  162. // ---------------------------------------------------------------------------
  163. //  Local helper methods
  164. // ---------------------------------------------------------------------------
  165. static void usage()
  166. {
  167.     cout << "nUsage:n"
  168.             "    PParse [options] <XML file>nn"
  169.             "This program demonstrates the progressive parse capabilities ofn"
  170.          "the parser system. It allows you to do a scanFirst() call followed byn"
  171.             "a loop which calls scanNext(). You can drop out when you've found whatn"
  172.             "ever it is you want. In our little test, our event handler looks forn"
  173.             "16 new elements then sets a flag to indicate its found what it wants.n"
  174.             "At that point, our progressive parse loop exits.nn"
  175.             "Options:n"
  176.             "      -v=xxx        - Validation scheme [always | never | auto*].n"
  177.             "      -n            - Enable namespace processing [default is off].n"
  178.             "      -s            - Enable schema processing [default is off].n"
  179.             "      -f            - Enable full schema constraint checking [default is off].n"
  180.             "      -?            - Show this help.nn"
  181.             "  * = Default if not provided explicitly.n"
  182.          <<  endl;
  183. }
  184. // ---------------------------------------------------------------------------
  185. //  Program entry point
  186. // ---------------------------------------------------------------------------
  187. int main(int argC, char* argV[])
  188. {
  189.     // Initialize the XML4C system
  190.     try
  191.     {
  192.          XMLPlatformUtils::Initialize();
  193.     }
  194.     catch (const XMLException& toCatch)
  195.     {
  196.          cerr << "Error during initialization! :n"
  197.               << StrX(toCatch.getMessage()) << endl;
  198.          return 1;
  199.     }
  200.     // Check command line and extract arguments.
  201.     if (argC < 2)
  202.     {
  203.         usage();
  204.         XMLPlatformUtils::Terminate();
  205.         return 1;
  206.     }
  207.     // See if non validating dom parser configuration is requested.
  208.     int parmInd;
  209.     for (parmInd = 1; parmInd < argC; parmInd++)
  210.     {
  211.         // Break out on first parm not starting with a dash
  212.         if (argV[parmInd][0] != '-')
  213.             break;
  214.         // Watch for special case help request
  215.         if (!strcmp(argV[parmInd], "-?"))
  216.         {
  217.             usage();
  218.             XMLPlatformUtils::Terminate();
  219.             return 2;
  220.         }
  221.          else if (!strncmp(argV[parmInd], "-v=", 3)
  222.               ||  !strncmp(argV[parmInd], "-V=", 3))
  223.         {
  224.             const char* const parm = &argV[parmInd][3];
  225.             if (!strcmp(parm, "never"))
  226.                 valScheme = SAXParser::Val_Never;
  227.             else if (!strcmp(parm, "auto"))
  228.                 valScheme = SAXParser::Val_Auto;
  229.             else if (!strcmp(parm, "always"))
  230.                 valScheme = SAXParser::Val_Always;
  231.             else
  232.             {
  233.                 cerr << "Unknown -v= value: " << parm << endl;
  234.                 XMLPlatformUtils::Terminate();
  235.                 return 2;
  236.             }
  237.         }
  238.          else if (!strcmp(argV[parmInd], "-n")
  239.               ||  !strcmp(argV[parmInd], "-N"))
  240.         {
  241.             doNamespaces = true;
  242.         }
  243.          else if (!strcmp(argV[parmInd], "-s")
  244.               ||  !strcmp(argV[parmInd], "-S"))
  245.         {
  246.             doSchema = true;
  247.         }
  248.          else if (!strcmp(argV[parmInd], "-f")
  249.               ||  !strcmp(argV[parmInd], "-F"))
  250.         {
  251.             schemaFullChecking = true;
  252.         }
  253.         else
  254.         {
  255.             cerr << "Unknown option '" << argV[parmInd]
  256.                 << "', ignoring itn" << endl;
  257.         }
  258.     }
  259.     //
  260.     //  And now we have to have only one parameter left and it must be
  261.     //  the file name.
  262.     //
  263.     if (parmInd + 1 != argC)
  264.     {
  265.         usage();
  266.         XMLPlatformUtils::Terminate();
  267.         return 1;
  268.     }
  269.     xmlFile = argV[parmInd];
  270.     int errorCount = 0;
  271.     //
  272.     //  Create a SAX parser object to use and create our SAX event handlers
  273.     //  and plug them in.
  274.     //
  275.     SAXParser* parser = new SAXParser;
  276.     PParseHandlers handler;
  277.     parser->setDocumentHandler(&handler);
  278.     parser->setErrorHandler(&handler);
  279.     parser->setValidationScheme(valScheme);
  280.     parser->setDoNamespaces(doNamespaces);
  281.     parser->setDoSchema(doSchema);
  282.     parser->setValidationSchemaFullChecking(schemaFullChecking);
  283.     //
  284.     //  Ok, lets do the progressive parse loop. On each time around the
  285.     //  loop, we look and see if the handler has found what its looking
  286.     //  for. When it does, we fall out then.
  287.     //
  288.     unsigned long duration;
  289.     try
  290.     {
  291.         // Create a progressive scan token
  292.         XMLPScanToken token;
  293.         const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
  294.         if (!parser->parseFirst(xmlFile, token))
  295.         {
  296.             cerr << "scanFirst() failedn" << endl;
  297.             XMLPlatformUtils::Terminate();
  298.             return 1;
  299.         }
  300.         //
  301.         //  We started ok, so lets call scanNext() until we find what we want
  302.         //  or hit the end.
  303.         //
  304.         bool gotMore = true;
  305.         while (gotMore && !parser->getErrorCount())
  306.             gotMore = parser->parseNext(token);
  307.         const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
  308.         duration = endMillis - startMillis;
  309.         errorCount = parser->getErrorCount();
  310.         //
  311.         //  Reset the parser-> In this simple progrma, since we just exit
  312.         //  now, its not technically required. But, in programs which
  313.         //  would remain open, you should reset after a progressive parse
  314.         //  in case you broke out before the end of the file. This insures
  315.         //  that all opened files, sockets, etc... are closed.
  316.         //
  317.         parser->parseReset(token);
  318.     }
  319.     catch (const XMLException& toCatch)
  320.     {
  321.         cerr << "nAn error occurred: '" << xmlFile << "'n"
  322.              << "Exception message is: n"
  323.              << StrX(toCatch.getMessage())
  324.              << "n" << endl;
  325.         XMLPlatformUtils::Terminate();
  326.         return 4;
  327.     }
  328.     if (!errorCount) {
  329.         cout << xmlFile << ": " << duration << " ms ("
  330.             << handler.getElementCount() << " elems, "
  331.             << handler.getAttrCount() << " attrs, "
  332.             << handler.getSpaceCount() << " spaces, "
  333.             << handler.getCharacterCount() << " chars)" << endl;
  334.     }
  335.     //
  336.     //  Delete the parser itself.  Must be done prior to calling Terminate, below.
  337.     //
  338.     delete parser;
  339.     // And call the termination method
  340.     XMLPlatformUtils::Terminate();
  341.     if (errorCount > 0)
  342.         return 4;
  343.     else
  344.         return 0;
  345. }